Cataclysm DDA
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | Friends | List of all members
game Class Reference

#include <game.h>

Classes

class  Creature_range
 
class  debug_hour_timer
 
class  draw_callback_t
 
class  monster_range
 
class  non_dead_range
 
class  npc_range
 

Public Types

enum  inventory_item_menu_position { RIGHT_TERMINAL_EDGE , LEFT_OF_INFO , RIGHT_OF_INFO , LEFT_TERMINAL_EDGE }
 
enum class  climb_maneuver { down , up , over_obstacle }
 Passed to climbing-related functions (slip_down) to indicate the climbing action being attempted. More...
 

Public Member Functions

 game ()
 
 ~game ()
 
void load_static_data ()
 Loads static data that does not depend on mods or similar. More...
 
void load_core_data (loading_ui &ui)
 Loads core dynamic data. More...
 
bool is_core_data_loaded () const
 Returns whether the core data is currently loaded. More...
 
bool check_mod_data (const std::vector< mod_id > &opts, loading_ui &ui)
 Check if mods can be successfully loaded. More...
 
void load_world_modfiles (loading_ui &ui)
 Loads core data and mods from the active world. More...
 
bool load_packs (const std::string &msg, const std::vector< mod_id > &packs, loading_ui &ui)
 Load content packs. More...
 
void on_options_changed ()
 Should be invoked whenever options change. More...
 
void setup ()
 
void serialize (std::ostream &fout)
 Saving and loading functions. More...
 
void unserialize (std::istream &fin, const cata_path &path)
 
void unserialize_master (const cata_path &file_name, std::istream &fin)
 
void unserialize_master (const JsonValue &jv)
 
bool save ()
 Returns false if saving failed. More...
 
std::vector< std::string > list_active_saves ()
 Returns a list of currently active character saves. More...
 
void write_memorial_file (std::string sLastWords)
 Writes information about the character out to a text file timestamped with the time of the file was made. More...
 
void start_calendar ()
 
shared_ptr_fast< ui_adaptorcreate_or_get_main_ui_adaptor ()
 
void invalidate_main_ui_adaptor () const
 
void mark_main_ui_adaptor_resize () const
 
void draw (ui_adaptor &ui)
 
void draw_ter (bool draw_sounds=true)
 
void draw_ter (const tripoint &center, bool looking=false, bool draw_sounds=true)
 
void add_draw_callback (const shared_ptr_fast< draw_callback_t > &cb)
 
void init_draw_async_anim_curses (const tripoint &p, const std::string &ncstr, const nc_color &nccol)
 
void draw_async_anim_curses ()
 
void void_async_anim_curses ()
 
void init_draw_blink_curses (const tripoint &p, const std::string &ncstr, const nc_color &nccol)
 
void draw_blink_curses ()
 
void void_blink_curses ()
 
bool has_blink_curses ()
 
void draw_panels (bool force_draw=false)
 
std::optional< tripointget_veh_dir_indicator_location (bool next) const
 Returns the location where the indicator should go relative to the reality bubble, or nothing to indicate no indicator should be drawn. More...
 
void draw_veh_dir_indicator (bool next)
 
void vertical_move (int z, bool force, bool peeking=false)
 Moves the player vertically. More...
 
void start_hauling (const tripoint &pos)
 
std::optional< tripointfind_or_make_stairs (map &mp, int z_after, bool &rope_ladder, bool peeking, const tripoint &pos)
 Returns the other end of the stairs (if any). More...
 
std::optional< tripointpoint_selection_menu (const std::vector< tripoint > &pts, bool up=true)
 
bool vertical_shift (int z_after)
 Actual z-level movement part of vertical_move. More...
 
void vertical_notes (int z_before, int z_after)
 Add goes up/down auto_notes (if turned on) More...
 
void use_computer (const tripoint &p)
 Checks to see if a player can use a computer (not illiterate, etc.) and uses if able. More...
 
template<typename T = Creature>
T * critter_by_id (const character_id &id)
 
template<typename T = Creature>
shared_ptr_fast< T > shared_from (const T &critter)
 Returns a shared pointer to the given critter (which can be of any of the subclasses of Creature). More...
 
size_t num_creatures () const
 Returns the approximate number of creatures in the reality bubble. More...
 
bool update_zombie_pos (const monster &critter, const tripoint_abs_ms &old_pos, const tripoint_abs_ms &new_pos)
 Redirects to the creature_tracker update_pos() function. More...
 
void remove_zombie (const monster &critter)
 
void clear_zombies ()
 Redirects to the creature_tracker clear() function. More...
 
bool spawn_hallucination (const tripoint &p)
 Spawns a hallucination at a determined position. More...
 
bool spawn_hallucination (const tripoint &p, const mtype_id &mt, std::optional< time_duration > lifespan)
 Spawns a hallucination at a determined position of a given monster. More...
 
bool spawn_npc (const tripoint &p, const string_id< npc_template > &npc_class, std::string &unique_id, std::vector< trait_id > &traits, std::optional< time_duration > lifespan)
 Spawns a npc at a determined position. More...
 
bool find_nearby_spawn_point (const tripoint &target, const mtype_id &mt, int min_radius, int max_radius, tripoint &point, bool outdoor_only, bool indoor_only, bool open_air_allowed=false)
 Finds somewhere to spawn a monster or npc. More...
 
bool find_nearby_spawn_point (const tripoint &target, int min_radius, int max_radius, tripoint &point, bool outdoor_only, bool indoor_only, bool open_air_allowed=false)
 
bool swap_critters (Creature &, Creature &)
 Swaps positions of two creatures. More...
 
Creature_range all_creatures ()
 Returns an anonymous range that contains all creatures. More...
 
monster_range all_monsters ()
 Same as all_creatures but iterators only over monsters. More...
 
npc_range all_npcs ()
 Same as all_creatures but iterators only over npcs. More...
 
std::vector< Creature * > get_creatures_if (const std::function< bool(const Creature &)> &pred)
 Returns all creatures matching a predicate. More...
 
std::vector< Character * > get_characters_if (const std::function< bool(const Character &)> &pred)
 
std::vector< npc * > get_npcs_if (const std::function< bool(const npc &)> &pred)
 
Creatureget_creature_if (const std::function< bool(const Creature &)> &pred)
 Returns a creature matching a predicate. More...
 
bool is_empty (const tripoint &p)
 Returns true if there is no player, NPC, or monster on the tile and move_cost > 0. More...
 
bool is_empty (const tripoint_bub_ms &p)
 
bool is_in_sunlight (const tripoint &p)
 Returns true if p is outdoors and it is sunny. More...
 
bool is_sheltered (const tripoint &p)
 Returns true if p is indoors, underground, or in a car. More...
 
bool revive_corpse (const tripoint &p, item &it)
 Revives a corpse at given location. More...
 
bool revive_corpse (const tripoint &p, item &it, int radius)
 
void save_cyborg (item *cyborg, const tripoint &couch_pos, Character &installer)
 Turns Broken Cyborg monster into Cyborg NPC via surgery. More...
 
bool cancel_activity_query (const std::string &text)
 Asks if the player wants to cancel their activity, and if so cancels it. More...
 
bool cancel_activity_or_ignore_query (distraction_type type, const std::string &text)
 Asks if the player wants to cancel their activity and if so cancels it. More...
 
bool portal_storm_query (distraction_type type, const std::string &text)
 
void moving_vehicle_dismount (const tripoint &dest_loc)
 Handles players exiting from moving vehicles. More...
 
vehicleremoteveh ()
 Returns the current remotely controlled vehicle. More...
 
void setremoteveh (vehicle *veh)
 Sets the current remotely controlled vehicle. More...
 
int assign_mission_id ()
 Returns the next available mission id. More...
 
npcfind_npc (character_id id)
 Find the npc with the given ID. More...
 
npcfind_npc_by_unique_id (const std::string &unique_id)
 Find the npc with the given unique ID. More...
 
void load_npcs ()
 Makes any nearby NPCs on the overmap active. More...
 
void reload_npcs ()
 Unloads, then loads the NPCs. More...
 
void remove_npc (character_id const &id)
 
const kill_trackerget_kill_tracker () const
 
stats_trackerstats ()
 
achievements_trackerachievements ()
 
void add_npc_follower (const character_id &id)
 Add follower id to set of followers. More...
 
void remove_npc_follower (const character_id &id)
 Remove follower id from follower set. More...
 
std::set< character_idget_follower_list ()
 Get set of followers. More...
 
void validate_npc_followers ()
 validate list of followers to account for overmap buffers More...
 
void validate_mounted_npcs ()
 
void validate_linked_vehicles ()
 validate towed vehicles so they get linked up again after a load More...
 
void validate_camps ()
 validate camps to ensure they are on the overmap list More...
 
void catch_a_monster (monster *fish, const tripoint &pos, Character *p, const time_duration &catch_duration)
 Picks and spawns a random fish from the remaining fish list when a fish is caught. More...
 
std::unordered_set< tripointget_fishable_locations (int distance, const tripoint &fish_pos)
 Get the contiguous fishable locations starting at fish_pos, out to the specified distance. More...
 
std::vector< monster * > get_fishable_monsters (std::unordered_set< tripoint > &fishable_locations)
 Get the fishable monsters within the provided fishable locations. More...
 
void water_affect_items (Character &ch) const
 Destroy / dissolve character items when in water. More...
 
bool fling_creature (Creature *c, const units::angle &dir, float flvel, bool controlled=false, bool intentional=false)
 Flings the input creature in the given direction. More...
 
float natural_light_level (int zlev) const
 
unsigned char light_level (int zlev) const
 Returns coarse number-of-squares of visibility at the current light level. More...
 
void reset_light_level ()
 
character_id assign_npc_id ()
 
Creatureis_hostile_nearby ()
 
Creatureis_hostile_very_close (bool dangerous=false)
 
field_entryis_in_dangerous_field ()
 
point update_map (Character &p, bool z_level_changed=false)
 
point update_map (int &x, int &y, bool z_level_changed=false)
 
void update_overmap_seen ()
 
void peek ()
 
void peek (const tripoint &p)
 
std::optional< tripointlook_debug ()
 
bool check_zone (const zone_type_id &type, const tripoint &where) const
 
bool check_near_zone (const zone_type_id &type, const tripoint &where) const
 Checks whether or not there is a zone of particular type nearby. More...
 
bool is_zones_manager_open () const
 
void zones_manager ()
 
std::optional< std::vector< tripoint_bub_ms > > safe_route_to (Character &who, const tripoint_bub_ms &target, int threshold, const std::function< void(const std::string &msg)> &report) const
 attempt to find a safe route (avoids tiles dangerous to 'who'). More...
 
std::optional< tripointlook_around ()
 
look_around_result look_around (bool show_window, tripoint &center, const tripoint &start_point, bool has_first_point, bool select_zone, bool peeking, bool is_moving_zone=false, const tripoint &end_point=tripoint_zero, bool change_lv=true)
 
look_around_result look_around (look_around_params)
 
void pre_print_all_tile_info (const tripoint &lp, const catacurses::window &w_info, int &line, int last_line, const visibility_variables &cache)
 
void print_all_tile_info (const tripoint &lp, const catacurses::window &w_look, const std::string &area_name, int column, int &line, int last_line, const visibility_variables &cache)
 
void draw_look_around_cursor (const tripoint &lp, const visibility_variables &cache)
 
void extended_description (const tripoint &p)
 Long description of (visible) things at tile. More...
 
void draw_trail_to_square (const tripoint &t, bool bDrawX)
 
int inventory_item_menu (item_location locThisItem, const std::function< int()> &startx=[]() { return 0;}, const std::function< int()> &width=[]() { return 50;}, inventory_item_menu_position position=RIGHT_OF_INFO)
 
item_location inv_map_splice (const item_filter &filter, const std::string &title, int radius=0, const std::string &none_message="")
 Custom-filtered menu for inventory and nearby items and those that within specified radius. More...
 
item_location inv_map_splice (const item_location_filter &filter, const std::string &title, int radius=0, const std::string &none_message="")
 
bool has_gametype () const
 
special_game_type gametype () const
 
void toggle_fullscreen ()
 
void toggle_pixel_minimap () const
 
void toggle_language_to_en ()
 
bool is_tileset_isometric () const
 
void reload_tileset ()
 
void temp_exit_fullscreen ()
 
void reenter_fullscreen ()
 
void zoom_in_overmap ()
 
void zoom_out_overmap ()
 
void zoom_in ()
 
void zoom_out ()
 
void reset_zoom ()
 
void set_zoom (int level)
 
int get_zoom () const
 
int get_moves_since_last_save () const
 
int get_user_action_counter () const
 
bool take_screenshot (const std::string &file_path) const
 Saves a screenshot of the current viewport, as a PNG file, to the given location. More...
 
bool take_screenshot () const
 Saves a screenshot of the current viewport, as a PNG file. More...
 
void load_map (const tripoint_abs_sm &pos_sm, bool pump_events=false)
 Load the main map at given location, see map::load, in global, absolute submap coordinates. More...
 
overmapget_cur_om () const
 The overmap which contains the center submap of the reality bubble. More...
 
std::vector< npc * > allies ()
 Get all living player allies. More...
 
void set_driving_view_offset (const point &p)
 
void calc_driving_offset (vehicle *veh=nullptr)
 
void open_gate (const tripoint &p)
 
void open_gate (const tripoint_bub_ms &p)
 
void knockback (const tripoint &s, const tripoint &t, int force, int stun, int dam_mult)
 
void knockback (std::vector< tripoint > &traj, int stun, int dam_mult)
 
void draw_bullet (const tripoint &t, int i, const std::vector< tripoint > &trajectory, char bullet)
 
void draw_hit_mon (const tripoint &p, const monster &m, bool dead=false)
 
void draw_hit_player (const Character &p, int dam)
 
void draw_line (const tripoint &p, const tripoint &center_point, const std::vector< tripoint > &points, bool noreveal=false)
 
void draw_line (const tripoint_bub_ms &p, const tripoint_bub_ms &center_point, const std::vector< tripoint_bub_ms > &points, bool noreveal=false)
 
void draw_line (const tripoint &p, const std::vector< tripoint > &points)
 
void draw_weather (const weather_printable &wPrint) const
 
void draw_sct () const
 
void draw_zones (const tripoint &start, const tripoint &end, const tripoint &offset) const
 
void draw_critter (const Creature &critter, const tripoint &center)
 
void draw_cursor (const tripoint &p) const
 
void draw_highlight (const tripoint &p)
 
void draw_async_anim (const tripoint &p, const std::string &tile_id, const std::string &ncstr="", const nc_color &nccol=c_black)
 
void draw_radiation_override (const tripoint &p, int rad)
 
void draw_terrain_override (const tripoint &p, const ter_id &id)
 
void draw_furniture_override (const tripoint &p, const furn_id &id)
 
void draw_graffiti_override (const tripoint &p, bool has)
 
void draw_trap_override (const tripoint &p, const trap_id &id)
 
void draw_field_override (const tripoint &p, const field_type_id &id)
 
void draw_item_override (const tripoint &p, const itype_id &id, const mtype_id &mid, bool hilite)
 
void draw_vpart_override (const tripoint &p, const vpart_id &id, int part_mod, const units::angle &veh_dir, bool hilite, const point &mount)
 
void draw_below_override (const tripoint &p, bool draw)
 
void draw_monster_override (const tripoint &p, const mtype_id &id, int count, bool more, Creature::Attitude att)
 
bool is_in_viewport (const tripoint &p, int margin=0) const
 
bool check_safe_mode_allowed (bool repeat_safe_mode_warnings=true)
 Check whether movement is allowed according to safe mode settings. More...
 
void set_safe_mode (safe_mode_type mode)
 
void exam_appliance (vehicle &veh, const point &cp=point_zero)
 open appliance interaction screen More...
 
void exam_vehicle (vehicle &veh, const point &cp=point_zero)
 open vehicle interaction screen More...
 
bool forced_door_closing (const tripoint &p, const ter_id &door_type, int bash_dmg)
 
bool forced_door_closing (const tripoint_bub_ms &p, const ter_id &door_type, int bash_dmg)
 
bool load (const std::string &world)
 Attempt to load first valid save (if any) in world. More...
 
bool npc_menu (npc &who)
 Returns true if the menu handled stuff and player shouldn't do anything else. More...
 
bool phasing_move (const tripoint &dest, bool via_ramp=false)
 
bool can_move_furniture (tripoint fdest, const tripoint &dp)
 
bool walk_move (const tripoint &dest, bool via_ramp=false, bool furniture_move=false)
 
void on_move_effects ()
 
int grabbed_furn_move_time (const tripoint &dp)
 
bool grabbed_furn_move (const tripoint &dp)
 
void reload_item ()
 
void reload_wielded (bool prompt=false)
 
void reload_weapon (bool try_everything=true)
 
void insert_item ()
 
void insert_item (drop_locations &targets)
 
point place_player (const tripoint &dest, bool quick=false)
 
void place_player_overmap (const tripoint_abs_omt &om_dest, bool move_player=true)
 
void perhaps_add_random_npc (bool ignore_spawn_timers_and_rates)
 
unsigned int get_seed () const
 
void set_npcs_dirty ()
 If invoked, NPCs will be reloaded before next turn. More...
 
void set_critter_died ()
 If invoked, dead will be cleaned this turn. More...
 
void mon_info_update ()
 
void cleanup_dead ()
 
bool is_dangerous_tile (const tripoint &dest_loc) const
 
std::vector< std::string > get_dangerous_tile (const tripoint &dest_loc) const
 
bool prompt_dangerous_tile (const tripoint &dest_loc) const
 
void pickup (const tripoint &p)
 
void despawn_monster (monster &critter)
 Despawn a specific monster, it's stored on the overmap. More...
 
void despawn_nonlocal_monsters ()
 
bool disable_robot (const tripoint &p)
 If there is a robot (that can be disabled), query the player and try to disable it. More...
 
void draw_pixel_minimap (const catacurses::window &w)
 
void quicksave ()
 
void quickload ()
 
void disp_NPCs ()
 
void list_missions ()
 
void update_unique_npc_location (const std::string &id, point_abs_om loc)
 
point_abs_om get_unique_npc_location (const std::string &id)
 
bool unique_npc_exists (const std::string &id)
 
void unique_npc_despawn (const std::string &id)
 
spell_eventsspell_events_subscriber ()
 
void display_toggle_overlay (action_id)
 
bool display_overlay_state (action_id)
 
void toggle_debug_hour_timer ()
 
tripoint mouse_edge_scrolling_terrain (input_context &ctxt)
 Used to implement mouse "edge scrolling". More...
 
tripoint mouse_edge_scrolling_overmap (input_context &ctxt)
 This variant is suitable for the overmap. More...
 
void shift_destination_preview (const point &delta)
 
bool slip_down (climb_maneuver maneuver, climbing_aid_id aid=climbing_aid_id::NULL_ID(), bool show_chance_messages=true)
 Checks if player is able to successfully climb to/from some terrain and not slip down. More...
 
int slip_down_chance (climb_maneuver maneuver, climbing_aid_id aid=climbing_aid_id::NULL_ID(), bool show_chance_messages=true)
 Calculates the chance that slip_down will return true. More...
 
void climb_down (const tripoint &examp)
 Climb down from a ledge. More...
 
void climb_down_menu_gen (const tripoint &examp, uilist &cmenu)
 
bool climb_down_menu_pick (const tripoint &examp, int retval)
 
void climb_down_using (const tripoint &examp, climbing_aid_id aid, bool deploy_affordance=false)
 
monsterplace_critter_at (const mtype_id &id, const tripoint &p)
 Adds critters to the reality bubble, creating them if necessary. More...
 
monsterplace_critter_at (const shared_ptr_fast< monster > &mon, const tripoint &p)
 
monsterplace_critter_around (const mtype_id &id, const tripoint &center, int radius)
 
monsterplace_critter_around (const shared_ptr_fast< monster > &mon, const tripoint &center, int radius, bool forced=false)
 
monsterplace_critter_within (const mtype_id &id, const tripoint_range< tripoint > &range)
 
monsterplace_critter_within (const shared_ptr_fast< monster > &mon, const tripoint_range< tripoint > &range)
 

Static Public Member Functions

static void display_om_pathfinding_progress (size_t open_set, size_t known_size)
 

Public Attributes

bool blink_active_phase = true
 
std::vector< effect_on_condition_idinactive_global_effect_on_condition_vector
 
queued_eocs queued_global_effect_on_conditions
 
pimpl< creature_trackercritter_tracker
 
pimpl< faction_managerfaction_manager_ptr
 
quit_status uquit
 Used in main.cpp to determine what type of quit is being performed. More...
 
bool new_game = false
 True if the game has just started or loaded, else false. More...
 
tripoint ter_view_p
 
catacurses::window w_terrain
 
catacurses::window w_overmap
 
catacurses::window w_omlegend
 
catacurses::window w_minimap
 
catacurses::window w_pixel_minimap
 
point driving_view_offset
 
bool debug_pathfinding = false
 
Creaturedisplaying_visibility_creature
 Creature for which to display the visibility map. More...
 
int displaying_lighting_condition = 0
 Type of lighting condition overlay to display. More...
 
bool show_panel_adm = false
 
bool fullscreen = false
 
bool was_fullscreen = false
 
bool auto_travel_mode = false
 
bool queue_screenshot = false
 
safe_mode_type safe_mode
 
time_duration turnssincelastmon = 0_turns
 
int mostseen = 0
 

Protected Member Functions

void load_data_from_dir (const cata_path &path, const std::string &src, loading_ui &ui)
 Loads dynamic data from the given directory. More...
 

Protected Attributes

std::map< tripoint, std::pair< std::string, nc_color > > async_anim_layer_curses
 
std::map< tripoint, std::pair< std::string, nc_color > > blink_layer_curses
 

Private Types

enum class  vmenu_ret : int { CHANGE_TAB , QUIT , FIRE }
 

Private Member Functions

void unload_npcs ()
 Unloads all NPCs. More...
 
bool load (const save_t &name)
 
void load_master ()
 
bool start_game ()
 
bool save_factions_missions_npcs ()
 
void reset_npc_dispositions ()
 
void serialize_master (std::ostream &fout)
 
bool save_maps ()
 
void init_autosave ()
 
void create_starting_npcs ()
 
vehicleplace_vehicle_nearby (const vproto_id &id, const point_abs_omt &origin, int min_distance, int max_distance, const std::vector< std::string > &omt_search_types={})
 
void list_items_monsters ()
 
game::vmenu_ret list_items (const std::vector< map_item_stack > &item_list)
 
std::vector< map_item_stackfind_nearby_items (int iRadius)
 
void reset_item_list_state (const catacurses::window &window, int height, bool bRadiusSort)
 
game::vmenu_ret list_monsters (const std::vector< Creature * > &monster_list)
 
bool grabbed_move (const tripoint &dp, bool via_ramp)
 Check for dangerous stuff at dest_loc, return false if the player decides not to step there. More...
 
bool grabbed_veh_move (const tripoint &dp)
 
void control_vehicle ()
 
void examine (const tripoint &p, bool with_pickup=false)
 
void examine (bool with_pickup=true)
 
void pickup ()
 
void pickup_all ()
 
void unload_container ()
 
void drop_in_direction (const tripoint &pnt)
 
void butcher ()
 
void reload (item_location &loc, bool prompt=false, bool empty=true)
 
void wield ()
 
void wield (item_location loc)
 
void chat ()
 
void print_fields_info (const tripoint &lp, const catacurses::window &w_look, int column, int &line)
 
void print_terrain_info (const tripoint &lp, const catacurses::window &w_look, const std::string &area_name, int column, int &line)
 
void print_furniture_info (const tripoint &lp, const catacurses::window &w_look, int column, int &line)
 
void print_trap_info (const tripoint &lp, const catacurses::window &w_look, int column, int &line)
 
void print_part_con_info (const tripoint &lp, const catacurses::window &w_look, int column, int &line)
 
void print_creature_info (const Creature *creature, const catacurses::window &w_look, int column, int &line, int last_line)
 
void print_vehicle_info (const vehicle *veh, int veh_part, const catacurses::window &w_look, int column, int &line, int last_line)
 
void print_visibility_info (const catacurses::window &w_look, int column, int &line, visibility_type visibility)
 
void print_items_info (const tripoint &lp, const catacurses::window &w_look, int column, int &line, int last_line)
 
void print_graffiti_info (const tripoint &lp, const catacurses::window &w_look, int column, int &line, int last_line)
 
input_context get_player_input (std::string &action)
 
void shift_monsters (const tripoint &shift)
 Shift all active monsters, the shift vector is the number of shifted submaps. More...
 
void open_consume_item_menu ()
 
bool do_regular_action (action_id &act, avatar &player_character, const std::optional< tripoint > &mouse_target)
 
bool handle_action ()
 
bool try_get_right_click_action (action_id &act, const tripoint_bub_ms &mouse_target)
 
bool try_get_left_click_action (action_id &act, const tripoint_bub_ms &mouse_target)
 
void item_action_menu (item_location loc=item_location())
 
bool is_game_over ()
 
void bury_screen () const
 
void death_screen ()
 
void draw_minimap ()
 
void autosave ()
 
bool handle_mouseview (input_context &ctxt, std::string &action)
 
void display_faction_epilogues ()
 
void disp_NPC_epilogues ()
 
void display_scent ()
 
void display_temperature ()
 
void display_vehicle_ai ()
 
void display_visibility ()
 
void display_lighting ()
 
void display_radiation ()
 
void display_transparency ()
 
Creatureis_hostile_within (int distance, bool dangerous=false)
 Checks if there's a hostile creature within given distance. More...
 
void move_save_to_graveyard ()
 
bool save_player_data ()
 
bool save_achievements ()
 
event_busevents ()
 
memorial_loggermemorial ()
 
std::pair< tripoint, tripointmouse_edge_scrolling (input_context &ctxt, int speed, const tripoint &last, bool iso)
 

Private Attributes

bool is_looking = false
 
std::vector< weak_ptr_fast< draw_callback_t > > draw_callbacks
 
std::optional< action_iddisplaying_overlays
 
class game::debug_hour_timer debug_hour_timer
 
pimpl< mapmap_ptr
 
pimpl< avataru_ptr
 
pimpl< live_viewliveview_ptr
 
live_viewliveview
 
pimpl< scent_mapscent_ptr
 
pimpl< timed_event_managertimed_event_manager_ptr
 
pimpl< event_busevent_bus_ptr
 
pimpl< stats_trackerstats_tracker_ptr
 
pimpl< achievements_trackerachievements_tracker_ptr
 
pimpl< kill_trackerkill_tracker_ptr
 
pimpl< memorial_loggermemorial_logger_ptr
 
pimpl< spell_eventsspell_events_ptr
 
pimpl< eoc_eventseoc_events_ptr
 
mapm
 
avataru
 
scent_mapscent
 
const scenarioscen = nullptr
 
timed_event_managertimed_events
 
global_variables global_variables_instance
 
std::unordered_map< std::string, point_abs_omunique_npcs
 
weather_manager weather
 
shared_ptr_fast< Characteru_shared_ptr
 
catacurses::window w_terrain_ptr
 
catacurses::window w_minimap_ptr
 
std::string sFilter
 
std::string list_item_upvote
 
std::string list_item_downvote
 
bool safe_mode_warning_logged = false
 
bool bVMonsterLookFire = false
 
character_id next_npc_id
 
int next_mission_id = 0
 
std::set< character_idfollower_ids
 
std::chrono::seconds time_played_at_last_load
 
std::chrono::time_point< std::chrono::steady_clock > time_of_last_load
 
int moves_since_last_save = 0
 
std::time_t last_save_timestamp = 0
 
std::array< float, OVERMAP_LAYERSlatest_lightlevels
 
time_point remoteveh_cache_time
 
vehicleremoteveh_cache
 
bool npcs_dirty = false
 Has a NPC been spawned since last load? More...
 
bool critter_died = false
 Has anything died in this turn and needs to be cleaned up? More...
 
bool first_redraw_since_waiting_started = true
 Is this the first redraw since waiting (sleeping or activity) started. More...
 
bool zones_manager_open = false
 Is Zone manager open or not - changes graphics of some zone tiles. More...
 
std::unique_ptr< special_gamegamemode
 
int user_action_counter = 0
 
int tileset_zoom = 0
 How far the tileset should be zoomed out, 16 is default. More...
 
int overmap_tileset_zoom = DEFAULT_TILESET_ZOOM
 
unsigned int seed = 0
 Seed for all the random numbers that should have consistent randomness (weather). More...
 
std::vector< tripoint_bub_msdestination_preview
 
std::chrono::time_point< std::chrono::steady_clock > last_mouse_edge_scroll
 
tripoint last_mouse_edge_scroll_vector_terrain
 
tripoint last_mouse_edge_scroll_vector_overmap
 
weak_ptr_fast< ui_adaptormain_ui_adaptor
 
std::unique_ptr< static_popupwait_popup
 

Friends

class editmap
 
class advanced_inventory
 
class main_menu
 
class exosuit_interact
 
class monster_range
 
class Creature_range
 
achievements_trackerget_achievements ()
 
event_busget_event_bus ()
 
mapget_map ()
 
creature_trackerget_creature_tracker ()
 
Characterget_player_character ()
 
avatarget_avatar ()
 
viewerget_player_view ()
 
weather_managerget_weather ()
 
const scenarioget_scenario ()
 
void set_scenario (const scenario *new_scenario)
 
stats_trackerget_stats ()
 
scent_mapget_scent ()
 
timed_event_managerget_timed_events ()
 
memorial_loggerget_memorial ()
 
bool do_turn ()
 MAIN GAME LOOP. More...
 
bool turn_handler::cleanup_at_end ()
 
global_variablesget_globals ()
 

Detailed Description

Definition at line 142 of file game.h.

Member Enumeration Documentation

◆ climb_maneuver

enum game::climb_maneuver
strong

Passed to climbing-related functions (slip_down) to indicate the climbing action being attempted.

Enumerator
down 
up 
over_obstacle 

Definition at line 1234 of file game.h.

1234  {
1235  down, // climb up one Z-level
1236  up, // climb down one Z-level
1237  over_obstacle, // climb over an obstacle (horizontal move)
1238  };
@ up
Definition: input.h:100
@ down
Definition: input.h:99

◆ inventory_item_menu_position

Enumerator
RIGHT_TERMINAL_EDGE 
LEFT_OF_INFO 
RIGHT_OF_INFO 
LEFT_TERMINAL_EDGE 

Definition at line 666 of file game.h.

666  {
668  LEFT_OF_INFO,
671  };
@ LEFT_OF_INFO
Definition: game.h:668
@ RIGHT_OF_INFO
Definition: game.h:669
@ RIGHT_TERMINAL_EDGE
Definition: game.h:667
@ LEFT_TERMINAL_EDGE
Definition: game.h:670

◆ vmenu_ret

enum game::vmenu_ret : int
strongprivate
Enumerator
CHANGE_TAB 
QUIT 
FIRE 

Definition at line 872 of file game.h.

872  : int {
873  CHANGE_TAB,
874  QUIT,
875  FIRE, // Who knew, apparently you can do that in list_monsters
876  };

Constructor & Destructor Documentation

◆ game()

game::game ( )

Definition at line 435 of file game.cpp.

435  :
437  scent_ptr( *this ),
439  m( *map_ptr ),
440  u( *u_ptr ),
441  scent( *scent_ptr ),
443  uquit( QUIT_NO ),
445  u_shared_ptr( &u, null_deleter{} ),
446  next_npc_id( 1 ),
447  next_mission_id( 1 ),
450  last_mouse_edge_scroll( std::chrono::steady_clock::now() )
451 {
460  world_generator = std::make_unique<worldfactory>();
461  // do nothing, everything that was in here is moved to init_data() which is called immediately after g = new game; in main.cpp
462  // The reason for this move is so that g is not uninitialized when it gets to installing the parts into vehicles.
463 }
void subscribe(event_subscriber *)
Definition: event_bus.cpp:55
pimpl< spell_events > spell_events_ptr
Definition: game.h:1074
safe_mode_type safe_mode
Definition: game.h:1140
pimpl< timed_event_manager > timed_event_manager_ptr
Definition: game.h:1068
std::chrono::time_point< std::chrono::steady_clock > last_mouse_edge_scroll
Definition: game.h:1206
quit_status uquit
Used in main.cpp to determine what type of quit is being performed.
Definition: game.h:1103
event_bus & events()
Definition: game.cpp:3422
pimpl< stats_tracker > stats_tracker_ptr
Definition: game.h:1070
character_id next_npc_id
Definition: game.h:1166
pimpl< kill_tracker > kill_tracker_ptr
Definition: game.h:1072
void reset_light_level()
Definition: game.cpp:4458
pimpl< memorial_logger > memorial_logger_ptr
Definition: game.h:1073
pimpl< map > map_ptr
Definition: game.h:1063
bool first_redraw_since_waiting_started
Is this the first redraw since waiting (sleeping or activity) started.
Definition: game.h:1186
pimpl< live_view > liveview_ptr
Definition: game.h:1065
pimpl< achievements_tracker > achievements_tracker_ptr
Definition: game.h:1071
pimpl< scent_map > scent_ptr
Definition: game.h:1067
timed_event_manager & timed_events
Definition: game.h:1084
int next_mission_id
Definition: game.h:1167
map & m
Definition: game.h:1077
avatar & u
Definition: game.h:1078
shared_ptr_fast< Character > u_shared_ptr
Definition: game.h:1154
pimpl< eoc_events > eoc_events_ptr
Definition: game.h:1075
scent_map & scent
Definition: game.h:1079
live_view & liveview
Definition: game.h:1066
int tileset_zoom
How far the tileset should be zoomed out, 16 is default.
Definition: game.h:1196
pimpl< avatar > u_ptr
Definition: game.h:1064
time_point remoteveh_cache_time
Definition: game.h:1179
static void achievement_attained(const achievement *a, bool achievements_enabled)
Definition: game.cpp:392
static void achievement_failed(const achievement *a, bool achievements_enabled)
Definition: game.cpp:423
constexpr int DEFAULT_TILESET_ZOOM
Definition: game.h:38
@ SAFE_MODE_ON
Definition: game.h:63
@ QUIT_NO
Definition: game.h:53
constexpr time_point before_time_starts
A time point that is always before the current turn, even when the game has just started.
Definition: calendar.h:535
For use with smart pointers when you don't actually want the deleter to do anything.
Definition: cata_utility.h:45
std::unique_ptr< worldfactory > world_generator

References achievements_tracker_ptr, eoc_events_ptr, events(), first_redraw_since_waiting_started, kill_tracker_ptr, memorial_logger_ptr, reset_light_level(), spell_events_ptr, stats_tracker_ptr, event_bus::subscribe(), u, and world_generator.

◆ ~game()

game::~game ( )
default

Member Function Documentation

◆ achievements()

achievements_tracker & game::achievements ( )

Definition at line 3432 of file game.cpp.

3433 {
3434  return *achievements_tracker_ptr;
3435 }

References achievements_tracker_ptr.

◆ add_draw_callback()

void game::add_draw_callback ( const shared_ptr_fast< draw_callback_t > &  cb)

Definition at line 3833 of file game.cpp.

3834 {
3835  draw_callbacks.erase(
3836  std::remove_if( draw_callbacks.begin(), draw_callbacks.end(),
3837  []( const weak_ptr_fast<draw_callback_t> &cbw ) {
3838  return cbw.expired();
3839  } ),
3840  draw_callbacks.end()
3841  );
3842  draw_callbacks.emplace_back( cb );
3843  cb->added = true;
3845 }
void invalidate_main_ui_adaptor() const
Definition: game.cpp:3798
std::vector< weak_ptr_fast< draw_callback_t > > draw_callbacks
Definition: game.h:247
std::weak_ptr< T > weak_ptr_fast
Definition: memory_fast.h:17

References draw_callbacks, and invalidate_main_ui_adaptor().

Referenced by get_player_input(), list_items(), list_monsters(), look_around(), pickup(), and zones_manager().

◆ add_npc_follower()

void game::add_npc_follower ( const character_id id)

Add follower id to set of followers.

Definition at line 1725 of file game.cpp.

1726 {
1727  follower_ids.insert( id );
1728  u.follower_ids.insert( id );
1729 }
std::set< character_id > follower_ids
Definition: avatar.h:379
std::set< character_id > follower_ids
Definition: game.h:1169

References avatar::follower_ids, follower_ids, and u.

Referenced by validate_npc_followers().

◆ all_creatures()

game::Creature_range game::all_creatures ( )

Returns an anonymous range that contains all creatures.

The range allows iteration via a range-based for loop, e.g. for( Creature &critter : all_creatures() ) { ... }. One shall not store the returned range nor the iterators. One can freely remove and add creatures to the game during the iteration. Added creatures will not be iterated over.

Definition at line 13223 of file game.cpp.

13224 {
13225  return Creature_range( *this );
13226 }
friend class Creature_range
Definition: game.h:389

References Creature_range.

Referenced by draw_ter(), get_creature_if(), and get_creatures_if().

◆ all_monsters()

game::monster_range game::all_monsters ( )

Same as all_creatures but iterators only over monsters.

Definition at line 13228 of file game.cpp.

13229 {
13230  return monster_range( *this );
13231 }
friend class monster_range
Definition: game.h:388

References monster_range.

Referenced by disp_NPCs(), get_fishable_monsters(), place_player_overmap(), shift_monsters(), start_game(), validate_mounted_npcs(), and vertical_move().

◆ all_npcs()

game::npc_range game::all_npcs ( )

Same as all_creatures but iterators only over npcs.

Definition at line 13233 of file game.cpp.

13234 {
13235  return npc_range( *this );
13236 }

Referenced by cancel_activity_query(), get_characters_if(), and get_npcs_if().

◆ allies()

std::vector< npc * > game::allies ( )

Get all living player allies.

Definition at line 13119 of file game.cpp.

13120 {
13121  return get_npcs_if( [&]( const npc & guy ) {
13122  if( !guy.is_hallucination() ) {
13123  return guy.is_ally( get_player_character() );
13124  } else {
13125  return false;
13126  }
13127  } );
13128 }
std::vector< npc * > get_npcs_if(const std::function< bool(const npc &)> &pred)
Definition: game.cpp:13158
Definition: npc.h:792
bool is_hallucination() const override
Definition: npc.h:911

References get_npcs_if(), and npc::is_hallucination().

◆ assign_mission_id()

int game::assign_mission_id ( )

Returns the next available mission id.

Definition at line 1708 of file game.cpp.

1709 {
1710  int ret = next_mission_id;
1711  next_mission_id++;
1712  return ret;
1713 }

References next_mission_id, and cata::hash64_detail::ret.

◆ assign_npc_id()

character_id game::assign_npc_id ( )

Definition at line 4466 of file game.cpp.

4467 {
4469  ++next_npc_id;
4470  return ret;
4471 }

References next_npc_id, and cata::hash64_detail::ret.

Referenced by load(), and start_game().

◆ autosave()

void game::autosave ( )
private

Definition at line 13093 of file game.cpp.

13094 {
13095  //Don't autosave if the min-autosave interval has not passed since the last autosave/quicksave.
13096  if( std::time( nullptr ) < last_save_timestamp + 60 * get_option<int>( "AUTOSAVE_MINUTES" ) ) {
13097  return;
13098  }
13099  quicksave(); //Driving checks are handled by quicksave()
13100 }
std::time_t last_save_timestamp
Definition: game.h:1175
void quicksave()
Definition: game.cpp:13044

References last_save_timestamp, and quicksave().

◆ bury_screen()

void game::bury_screen ( ) const
private

Definition at line 2794 of file game.cpp.

2795 {
2796  avatar &u = get_avatar();
2797 
2798  std::vector<std::string> vRip;
2799 
2800  int iMaxWidth = 0;
2801  int iNameLine = 0;
2802  int iInfoLine = 0;
2803 
2806  if( !( u.has_trait( trait_CANNIBAL ) || u.has_trait( trait_PSYCHOPATH ) ) ) {
2807  vRip.emplace_back( " _______ ___" );
2808  vRip.emplace_back( " < `/ |" );
2809  vRip.emplace_back( " > _ _ (" );
2810  vRip.emplace_back( " | |_) | |_) |" );
2811  vRip.emplace_back( " | | \\ | | |" );
2812  vRip.emplace_back( " ______.__%_| |_________ __" );
2813  vRip.emplace_back( " _/ \\| |" );
2814  iNameLine = vRip.size();
2815  vRip.emplace_back( "| <" );
2816  vRip.emplace_back( "| |" );
2817  iMaxWidth = utf8_width( vRip.back() );
2818  vRip.emplace_back( "| |" );
2819  vRip.emplace_back( "|_____.-._____ __/|_________|" );
2820  vRip.emplace_back( " | |" );
2821  iInfoLine = vRip.size();
2822  vRip.emplace_back( " | |" );
2823  vRip.emplace_back( " | <" );
2824  vRip.emplace_back( " | |" );
2825  vRip.emplace_back( " | _ |" );
2826  vRip.emplace_back( " |__/ |" );
2827  vRip.emplace_back( " % / `--. |%" );
2828  vRip.emplace_back( " * .%%| -< @%%%" ); // NOLINT(cata-text-style)
2829  vRip.emplace_back( " `\\%`@| |@@%@%%" );
2830  vRip.emplace_back( " .%%%@@@|% ` % @@@%%@%%%%" );
2831  vRip.emplace_back( " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" );
2832 
2833  } else {
2834  vRip.emplace_back( " _______ ___" );
2835  vRip.emplace_back( " | \\/ |" );
2836  vRip.emplace_back( " | |" );
2837  vRip.emplace_back( " | |" );
2838  iInfoLine = vRip.size();
2839  vRip.emplace_back( " | |" );
2840  vRip.emplace_back( " | |" );
2841  vRip.emplace_back( " | |" );
2842  vRip.emplace_back( " | |" );
2843  vRip.emplace_back( " | <" );
2844  vRip.emplace_back( " | _ |" );
2845  vRip.emplace_back( " |__/ |" );
2846  vRip.emplace_back( " ______.__%_| |__________ _" );
2847  vRip.emplace_back( " _/ \\| \\" );
2848  iNameLine = vRip.size();
2849  vRip.emplace_back( "| <" );
2850  vRip.emplace_back( "| |" );
2851  iMaxWidth = utf8_width( vRip.back() );
2852  vRip.emplace_back( "| |" );
2853  vRip.emplace_back( "|_____.-._______ __/|__________|" );
2854  vRip.emplace_back( " % / `_-. _ |%" );
2855  vRip.emplace_back( " * .%%| |_) | |_)< @%%%" ); // NOLINT(cata-text-style)
2856  vRip.emplace_back( " `\\%`@| | \\ | | |@@%@%%" );
2857  vRip.emplace_back( " .%%%@@@|% ` % @@@%%@%%%%" );
2858  vRip.emplace_back( " _.%%%%%%@@@@@@%%%__/\\%@@%%@@@@@@@%%%%%%" );
2859  }
2860  } else {
2861  vRip.emplace_back( R"( _________ ____ )" );
2862  vRip.emplace_back( R"( _/ `/ \_ )" );
2863  vRip.emplace_back( R"( _/ _ _ \_. )" );
2864  vRip.emplace_back( R"( _%\ |_) | |_) \_ )" );
2865  vRip.emplace_back( R"( _/ \/ | \ | | \_ )" );
2866  vRip.emplace_back( R"( _/ \_ )" );
2867  vRip.emplace_back( R"(| |)" );
2868  iNameLine = vRip.size();
2869  vRip.emplace_back( R"( ) < )" );
2870  vRip.emplace_back( R"(| |)" );
2871  vRip.emplace_back( R"(| |)" );
2872  vRip.emplace_back( R"(| _ |)" );
2873  vRip.emplace_back( R"(|__/ |)" );
2874  iMaxWidth = utf8_width( vRip.back() );
2875  vRip.emplace_back( R"( / `--. |)" );
2876  vRip.emplace_back( R"(| ( )" );
2877  iInfoLine = vRip.size();
2878  vRip.emplace_back( R"(| |)" );
2879  vRip.emplace_back( R"(| |)" );
2880  vRip.emplace_back( R"(| % . |)" );
2881  vRip.emplace_back( R"(| @` %% |)" );
2882  vRip.emplace_back( R"(| %@%@%\ * %`%@%|)" );
2883  vRip.emplace_back( R"(%%@@@.%@%\%% `\ %%.%%@@%@)" );
2884  vRip.emplace_back( R"(@%@@%%%%%@@@@@@%%%%%%%%@@%%@@@%%%@%%@)" );
2885  }
2886 
2887  const point iOffset( TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0,
2888  TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 );
2889 
2891  iOffset );
2892  draw_border( w_rip );
2893 
2899 
2900  for( size_t iY = 0; iY < vRip.size(); ++iY ) {
2901  size_t iX = 0;
2902  const char *str = vRip[iY].data();
2903  for( int slen = vRip[iY].size(); slen > 0; ) {
2904  const uint32_t cTemp = UTF8_getch( &str, &slen );
2905  if( cTemp != U' ' ) {
2906  nc_color ncColor = c_light_gray;
2907 
2908  if( cTemp == U'%' ) {
2909  ncColor = c_green;
2910 
2911  } else if( cTemp == U'_' || cTemp == U'|' ) {
2912  ncColor = c_white;
2913 
2914  } else if( cTemp == U'@' ) {
2915  ncColor = c_brown;
2916 
2917  } else if( cTemp == U'*' ) {
2918  ncColor = c_red;
2919  }
2920 
2921  mvwputch( w_rip, point( iX + FULL_SCREEN_WIDTH / 2 - ( iMaxWidth / 2 ), iY + 1 ), ncColor,
2922  cTemp );
2923  }
2924  iX += mk_wcwidth( cTemp );
2925  }
2926  }
2927 
2928  std::string sTemp;
2929 
2930  center_print( w_rip, iInfoLine++, c_white, _( "Survived:" ) );
2931 
2933  const int minutes = to_minutes<int>( survived ) % 60;
2934  const int hours = to_hours<int>( survived ) % 24;
2935  const int days = to_days<int>( survived );
2936 
2937  if( days > 0 ) {
2938  // NOLINTNEXTLINE(cata-translate-string-literal)
2939  sTemp = string_format( "%dd %dh %dm", days, hours, minutes );
2940  } else if( hours > 0 ) {
2941  // NOLINTNEXTLINE(cata-translate-string-literal)
2942  sTemp = string_format( "%dh %dm", hours, minutes );
2943  } else {
2944  // NOLINTNEXTLINE(cata-translate-string-literal)
2945  sTemp = string_format( "%dm", minutes );
2946  }
2947 
2948  center_print( w_rip, iInfoLine++, c_white, sTemp );
2949 
2950  const int iTotalKills = g->get_kill_tracker().monster_kill_count();
2951 
2952  sTemp = _( "Kills:" );
2953  mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - 5, 1 + iInfoLine++ ), c_light_gray,
2954  ( sTemp + " " ) );
2955  wprintz( w_rip, c_magenta, "%d", iTotalKills );
2956 
2957  sTemp = _( "In memory of:" );
2958  mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - utf8_width( sTemp ) / 2, iNameLine++ ),
2959  c_light_gray,
2960  sTemp );
2961 
2962  sTemp = u.get_name();
2963  mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - utf8_width( sTemp ) / 2, iNameLine++ ), c_white,
2964  sTemp );
2965 
2966  sTemp = _( "Last Words:" );
2967  mvwprintz( w_rip, point( FULL_SCREEN_WIDTH / 2 - utf8_width( sTemp ) / 2, iNameLine++ ),
2968  c_light_gray,
2969  sTemp );
2970 
2971  int iStartX = FULL_SCREEN_WIDTH / 2 - ( ( iMaxWidth - 4 ) / 2 );
2972  std::string sLastWords = string_input_popup()
2973  .window( w_rip, point( iStartX, iNameLine ), iStartX + iMaxWidth - 4 - 1 )
2974  .max_length( iMaxWidth - 4 - 1 )
2975  .query_string();
2976 
2977  const bool is_suicide = uquit == QUIT_SUICIDE;
2979  sLastWords );
2980 }
uint32_t UTF8_getch(const char **src, int *srclen)
Definition: catacharset.cpp:20
int utf8_width(const std::string_view s, const bool ignore_tags)
std::string name
Definition: character.h:2684
bool male
Definition: character.h:2687
character_id getID() const
Definition: character.cpp:652
std::string get_name() const override
Definition: character.cpp:5731
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:111
Definition: avatar.h:84
A wrapper over a pointer to a curses window.
Definition: cursesdef.h:55
void send(const cata::event &) const
Definition: event_bus.cpp:72
friend event_bus & get_event_bus()
Definition: game.cpp:13832
friend avatar & get_avatar()
Definition: game.cpp:13817
friend Character & get_player_character()
Definition: game.cpp:13807
Shows a window querying the user for input.
string_input_popup & max_length(int value)
Maximal amount of Unicode characters that can be given by the user.
const std::string & query_string(bool loop=true, bool draw_only=false)
string_input_popup & window(const catacurses::window &w, const point &start, int endx)
Set the window area where to display the input text.
A duration defined as a number of specific time units.
Definition: calendar.h:197
bool has_amount(const itype_id &what, int qty, bool pseudo, const std::function< bool(const item &)> &filter) const
Definition: visitable.cpp:1018
#define c_white
Definition: color.h:16
#define c_light_gray
Definition: color.h:17
#define c_green
Definition: color.h:20
#define c_magenta
Definition: color.h:23
#define c_brown
Definition: color.h:24
#define c_red
Definition: color.h:19
static const itype_id itype_holybook_bible1("holybook_bible1")
static const itype_id itype_holybook_bible2("holybook_bible2")
static const trait_id trait_PSYCHOPATH("PSYCHOPATH")
static const itype_id itype_holybook_bible3("holybook_bible3")
std::unique_ptr< game > g
Definition: game.cpp:382
static const trait_id trait_CANNIBAL("CANNIBAL")
@ QUIT_SUICIDE
Definition: game.h:54
time_point start_of_game
Definition: calendar.cpp:37
time_point turn
Definition: calendar.cpp:38
window newwin(int nlines, int ncols, const point &begin)
Definition: ncurses_def.cpp:58
const size_t size
Definition: omdata.h:66
void do_player_death_hurt(const Character &target, bool death)
Definition: sounds.cpp:2033
void fade_audio_group(group group, int duration)
Definition: sounds.cpp:2017
int TERMX
Definition: output.cpp:49
void mvwprintz(const catacurses::window &w, const point &p, const nc_color &FG, const std::string &text)
Definition: output.cpp:3290
int FULL_SCREEN_HEIGHT
Definition: output.cpp:58
int TERMY
Definition: output.cpp:50
void center_print(const catacurses::window &w, const int y, const nc_color &FG, const std::string &text)
Definition: output.cpp:559
void wprintz(const catacurses::window &w, const nc_color &FG, const std::string &text)
Definition: output.cpp:3298
int FULL_SCREEN_WIDTH
Definition: output.cpp:57
void mvwputch(const catacurses::window &w, const point &p, nc_color FG, int ch)
Definition: output.cpp:590
void draw_border(const catacurses::window &w, nc_color border_color, const std::string &title, nc_color title_color)
Definition: output.cpp:688
std::string string_format(std::string_view format, Args &&...args)
Simple wrapper over string_formatter::parse.
Definition: point.h:20
#define _(STRING)
Definition: translations.h:89
int mk_wcwidth(uint32_t ucs)
Definition: wcwidth.cpp:94

References _, c_brown, c_green, c_light_gray, c_magenta, c_red, c_white, center_print(), sfx::context_themes, sfx::do_player_death_hurt(), draw_border(), sfx::fade_audio_group(), FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, g, game_avatar_death, get_avatar, get_event_bus, Character::get_name(), get_player_character, Character::getID(), visitable::has_amount(), Character::has_trait(), itype_holybook_bible1, itype_holybook_bible2, itype_holybook_bible3, Character::male, string_input_popup::max_length(), mk_wcwidth(), mvwprintz(), mvwputch(), Character::name, catacurses::newwin(), point, string_input_popup::query_string(), QUIT_SUICIDE, event_bus::send(), om_direction::size, sfx::sleepiness, calendar::start_of_game, string_format(), TERMX, TERMY, sfx::time_of_day, trait_CANNIBAL, trait_PSYCHOPATH, calendar::turn, u, uquit, UTF8_getch(), utf8_width(), sfx::weather, string_input_popup::window(), and wprintz().

Referenced by is_game_over().

◆ butcher()

void game::butcher ( )
private

Definition at line 9642 of file game.cpp.

9643 {
9644  static const std::string salvage_string = "salvage";
9645  if( u.controlling_vehicle ) {
9646  add_msg( m_info, _( "You can't butcher while driving!" ) );
9647  return;
9648  }
9649 
9650  const int factor = u.max_quality( qual_BUTCHER, PICKUP_RANGE );
9651  const int factorD = u.max_quality( qual_CUT_FINE, PICKUP_RANGE );
9652  const std::string no_knife_msg = _( "You don't have a butchering tool." );
9653  const std::string no_corpse_msg = _( "There are no corpses here to butcher." );
9654 
9655  //You can't butcher on sealed terrain- you have to smash/shovel/etc it open first
9657  if( m.sees_some_items( u.pos(), u ) ) {
9658  add_msg( m_info, _( "You can't access the items here." ) );
9659  } else if( factor > INT_MIN || factorD > INT_MIN ) {
9660  add_msg( m_info, no_corpse_msg );
9661  } else {
9662  add_msg( m_info, no_knife_msg );
9663  }
9664  return;
9665  }
9666 
9667  const item *first_item_without_tools = nullptr;
9668  // Indices of relevant items
9669  std::vector<map_stack::iterator> corpses;
9670  std::vector<map_stack::iterator> disassembles;
9671  std::vector<map_stack::iterator> salvageables;
9672  map_stack items = m.i_at( u.pos() );
9673  const inventory &crafting_inv = u.crafting_inventory();
9674 
9675  // TODO: Properly handle different material whitelists
9676  // TODO: Improve quality of this section
9677  auto salvage_filter = []( const item & it ) {
9678  const item *usable = it.get_usable_item( salvage_string );
9679  return usable != nullptr;
9680  };
9681 
9682  std::vector< item * > salvage_tools = u.items_with( salvage_filter );
9683  int salvage_tool_index = INT_MIN;
9684  item *salvage_tool = nullptr;
9685  const salvage_actor *salvage_iuse = nullptr;
9686  if( !salvage_tools.empty() ) {
9687  salvage_tool = salvage_tools.front();
9688  salvage_tool_index = u.get_item_position( salvage_tool );
9689  item *usable = salvage_tool->get_usable_item( salvage_string );
9690  salvage_iuse = dynamic_cast<const salvage_actor *>(
9691  usable->get_use( salvage_string )->get_actor_ptr() );
9692  }
9693 
9694  // Reserve capacity for each to hold entire item set if necessary to prevent
9695  // reallocations later on
9696  corpses.reserve( items.size() );
9697  salvageables.reserve( items.size() );
9698  disassembles.reserve( items.size() );
9699 
9700  // Split into corpses, disassemble-able, and salvageable items
9701  // It's not much additional work to just generate a corpse list and
9702  // clear it later, but does make the splitting process nicer.
9703  for( map_stack::iterator it = items.begin(); it != items.end(); ++it ) {
9704  if( it->is_corpse() ) {
9705  corpses.push_back( it );
9706  } else {
9707  if( ( salvage_tool_index != INT_MIN ) && salvage_iuse->valid_to_cut_up( nullptr, *it ) ) {
9708  salvageables.push_back( it );
9709  }
9710  if( u.can_disassemble( *it, crafting_inv ).success() ) {
9711  disassembles.push_back( it );
9712  } else if( !first_item_without_tools ) {
9713  first_item_without_tools = &*it;
9714  }
9715  }
9716  }
9717 
9718  // Clear corpses if butcher and dissect factors are INT_MIN
9719  if( factor == INT_MIN && factorD == INT_MIN ) {
9720  corpses.clear();
9721  }
9722 
9723  if( corpses.empty() && disassembles.empty() && salvageables.empty() ) {
9724  if( factor > INT_MIN || factorD > INT_MIN ) {
9725  add_msg( m_info, no_corpse_msg );
9726  } else {
9727  add_msg( m_info, no_knife_msg );
9728  }
9729 
9730  if( first_item_without_tools ) {
9731  add_msg( m_info, _( "You don't have the necessary tools to disassemble any items here." ) );
9732  // Just for the "You need x to disassemble y" messages
9733  const auto ret = u.can_disassemble( *first_item_without_tools, crafting_inv );
9734  if( !ret.success() ) {
9735  add_msg( m_info, "%s", ret.c_str() );
9736  }
9737  }
9738  return;
9739  }
9740 
9741  Creature *hostile_critter = is_hostile_very_close( true );
9742  if( hostile_critter != nullptr ) {
9743  if( !query_yn( _( "You see %s nearby! Start butchering anyway?" ),
9744  hostile_critter->disp_name() ) ) {
9745  return;
9746  }
9747  }
9748 
9749  // Magic indices for special butcher options
9750  enum : int {
9751  MULTISALVAGE = MAX_ITEM_IN_SQUARE + 1,
9752  MULTIBUTCHER,
9753  MULTIDISASSEMBLE_ONE,
9754  MULTIDISASSEMBLE_ALL,
9755  NUM_BUTCHER_ACTIONS
9756  };
9757  // What are we butchering (i.e.. which vector to pick indices from)
9758  enum {
9759  BUTCHER_CORPSE,
9760  BUTCHER_DISASSEMBLE,
9761  BUTCHER_SALVAGE,
9762  BUTCHER_OTHER // For multisalvage etc.
9763  } butcher_select = BUTCHER_CORPSE;
9764  // Index to std::vector of iterators...
9765  int indexer_index = 0;
9766 
9767  // Generate the indexed stacks so we can display them nicely
9768  const auto disassembly_stacks = generate_butcher_stack_display( disassembles );
9769  const auto salvage_stacks = generate_butcher_stack_display( salvageables );
9770  // Always ask before cutting up/disassembly, but not before butchery
9771  size_t ret = 0;
9772  if( !corpses.empty() || !disassembles.empty() || !salvageables.empty() ) {
9773  uilist kmenu;
9774  kmenu.text = _( "Choose corpse to butcher / item to disassemble" );
9775 
9776  size_t i = 0;
9777  // Add corpses, disassembleables, and salvagables to the UI
9778  add_corpses( kmenu, corpses, i );
9779  add_disassemblables( kmenu, disassembly_stacks, i );
9780  if( salvage_iuse && !salvageables.empty() ) {
9781  add_salvagables( kmenu, salvage_stacks, i, *salvage_iuse );
9782  }
9783 
9784  if( corpses.size() > 1 ) {
9785  kmenu.addentry( MULTIBUTCHER, true, 'b', _( "Butcher everything" ) );
9786  }
9787 
9788  if( disassembly_stacks.size() > 1 || ( disassembly_stacks.size() == 1 &&
9789  disassembly_stacks.front().second > 1 ) ) {
9790  int time_to_disassemble_once = 0;
9791  int time_to_disassemble_recursive = 0;
9792  for( const auto &stack : disassembly_stacks ) {
9793  recipe uncraft_recipe;
9794  if( stack.first->typeId() == itype_disassembly ) {
9795  uncraft_recipe = stack.first->get_making();
9796  } else {
9797  uncraft_recipe = recipe_dictionary::get_uncraft( stack.first->typeId() );
9798  }
9799 
9800  const int time = uncraft_recipe.time_to_craft_moves(
9802  time_to_disassemble_once += time * stack.second;
9803  if( stack.first->typeId() == itype_disassembly ) {
9804  item test( uncraft_recipe.result(), calendar::turn, 1 );
9805  time_to_disassemble_recursive += test.get_recursive_disassemble_moves(
9806  get_player_character() ) * stack.second;
9807  } else {
9808  time_to_disassemble_recursive += stack.first->get_recursive_disassemble_moves(
9809  get_player_character() ) * stack.second;
9810  }
9811 
9812  }
9813 
9814  kmenu.addentry_col( MULTIDISASSEMBLE_ONE, true, 'D', _( "Disassemble everything once" ),
9815  to_string_clipped( time_duration::from_moves( time_to_disassemble_once ) ) );
9816  kmenu.addentry_col( MULTIDISASSEMBLE_ALL, true, 'd', _( "Disassemble everything recursively" ),
9817  to_string_clipped( time_duration::from_moves( time_to_disassemble_recursive ) ) );
9818  }
9819  if( salvage_iuse && salvageables.size() > 1 ) {
9820  int time_to_salvage = 0;
9821  for( const auto &stack : salvage_stacks ) {
9822  time_to_salvage += salvage_iuse->time_to_cut_up( *stack.first ) * stack.second;
9823  }
9824 
9825  kmenu.addentry_col( MULTISALVAGE, true, 'z', _( "Cut up everything" ),
9826  to_string_clipped( time_duration::from_moves( time_to_salvage ) ) );
9827  }
9828 
9829  kmenu.query();
9830 
9831  if( kmenu.ret < 0 || kmenu.ret >= NUM_BUTCHER_ACTIONS ) {
9832  return;
9833  }
9834 
9835  ret = static_cast<size_t>( kmenu.ret );
9836  if( ret >= MULTISALVAGE && ret < NUM_BUTCHER_ACTIONS ) {
9837  butcher_select = BUTCHER_OTHER;
9838  indexer_index = ret;
9839  } else if( ret < corpses.size() ) {
9840  butcher_select = BUTCHER_CORPSE;
9841  indexer_index = ret;
9842  } else if( ret < corpses.size() + disassembly_stacks.size() ) {
9843  butcher_select = BUTCHER_DISASSEMBLE;
9844  indexer_index = ret - corpses.size();
9845  } else if( ret < corpses.size() + disassembly_stacks.size() + salvage_stacks.size() ) {
9846  butcher_select = BUTCHER_SALVAGE;
9847  indexer_index = ret - corpses.size() - disassembly_stacks.size();
9848  } else {
9849  debugmsg( "Invalid butchery index: %d", ret );
9850  return;
9851  }
9852  }
9853 
9854  if( !u.has_morale_to_craft() ) {
9855  if( butcher_select == BUTCHER_CORPSE || indexer_index == MULTIBUTCHER ) {
9856  add_msg( m_info,
9857  _( "You are not in the mood and the prospect of guts and blood on your hands convinces you to turn away." ) );
9858  } else {
9859  add_msg( m_info,
9860  _( "You are not in the mood and the prospect of work stops you before you begin." ) );
9861  }
9862  return;
9863  }
9864  const std::vector<Character *> helpers = u.get_crafting_helpers();
9865  for( std::size_t i = 0; i < helpers.size() && i < 3; i++ ) {
9866  add_msg( m_info, _( "%s helps with this task…" ), helpers[i]->get_name() );
9867  }
9868  switch( butcher_select ) {
9869  case BUTCHER_OTHER:
9870  switch( indexer_index ) {
9871  case MULTISALVAGE:
9872  u.assign_activity( longsalvage_activity_actor( salvage_tool_index ) );
9873  break;
9874  case MULTIBUTCHER:
9875  butcher_submenu( corpses );
9876  for( map_stack::iterator &it : corpses ) {
9877  u.activity.targets.emplace_back( map_cursor( u.pos() ), &*it );
9878  }
9879  break;
9880  case MULTIDISASSEMBLE_ONE:
9881  u.disassemble_all( true );
9882  break;
9883  case MULTIDISASSEMBLE_ALL:
9884  u.disassemble_all( false );
9885  break;
9886  default:
9887  debugmsg( "Invalid butchery type: %d", indexer_index );
9888  return;
9889  }
9890  break;
9891  case BUTCHER_CORPSE: {
9892  butcher_submenu( corpses, indexer_index );
9893  u.activity.targets.emplace_back( map_cursor( u.pos() ), &*corpses[indexer_index] );
9894  }
9895  break;
9896  case BUTCHER_DISASSEMBLE: {
9897  // Pick index of first item in the disassembly stack
9898  item *const target = &*disassembly_stacks[indexer_index].first;
9899  u.disassemble( item_location( map_cursor( u.pos() ), target ), true );
9900  }
9901  break;
9902  case BUTCHER_SALVAGE: {
9903  if( !salvage_iuse || !salvage_tool ) {
9904  debugmsg( "null salvage_iuse or salvage_tool" );
9905  } else {
9906  // Pick index of first item in the salvage stack
9907  item *const target = &*salvage_stacks[indexer_index].first;
9908  item_location item_loc( map_cursor( u.pos() ), target );
9909  salvage_iuse->try_to_cut_up( u, *salvage_tool, item_loc );
9910  }
9911  }
9912  break;
9913  }
9914 }
static std::string to_string_clipped(const int num, const clipped_unit type, const clipped_align align)
Definition: calendar.cpp:427
bool controlling_vehicle
Is currently in control of a vehicle.
Definition: character.h:559
player_activity activity
Definition: character.h:2709
int get_item_position(const item *it) const
Returns the item position (suitable for i_at or similar) of a specific item.
bool disassemble()
Definition: crafting.cpp:2577
std::vector< Character * > get_crafting_helpers() const
Return nearby Characters ready and willing to help with crafting.
Definition: crafting.cpp:3051
int max_quality(const quality_id &qual) const override
Return maximum tool quality level provided by instance or INT_MIN if not found.
ret_val< void > can_disassemble(const item &obj, const read_only_visitable &inv) const
Check if the player can disassemble an item using the current crafting inventory.
Definition: crafting.cpp:2463
bool has_morale_to_craft() const
Definition: crafting.cpp:389
void disassemble_all(bool one_pass)
Definition: crafting.cpp:2697
const inventory & crafting_inventory(bool clear_path) const
Definition: crafting.cpp:629
void assign_activity(const activity_id &type, int moves=calendar::INDEFINITELY_LONG, int index=-1, int pos=INT_MIN, const std::string &name="")
Definition: character.cpp:8935
tripoint pos() const
Definition: creature.cpp:178
virtual std::string disp_name(bool possessive=false, bool capitalize_first=false) const =0
Creature * is_hostile_very_close(bool dangerous=false)
Definition: game.cpp:4480
A lightweight handle to an item independent of it's location Unlike a raw pointer can be (de-)seriali...
Definition: item_location.h:29
size_t size() const
Definition: item_stack.cpp:14
iterator begin()
Definition: item_stack.cpp:32
iterator end()
Definition: item_stack.cpp:37
Definition: item.h:196
const item * get_usable_item(const std::string &use_name) const
Checks this item and its contents (recursively) for types that have use_function with type use_name.
Definition: item.cpp:11508
const use_function * get_use(const std::string &use_name) const
Returns the pointer to use_function with name use_name assigned to the type of this item or any of it...
Definition: item.cpp:11463
Definition: map.h:107
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:3077
map_stack i_at(const tripoint &p)
Definition: map.cpp:4978
bool sees_some_items(const tripoint &p, const Creature &who) const
Check if creature can see some items at p.
Definition: map.cpp:5855
std::vector< item_location > targets
static const recipe & get_uncraft(const itype_id &id)
Returns disassembly recipe (or null recipe if no match)
Definition: recipe.h:87
int64_t time_to_craft_moves(const Character &guy, recipe_time_flag flags=recipe_time_flag::none) const
Definition: recipe.cpp:92
const itype_id & result() const
Definition: recipe.h:111
bool success() const
Definition: ret_val.h:13
Cuts stuff up into components.
Definition: iuse_actor.h:501
bool valid_to_cut_up(const Character *p, const item &it) const
int time_to_cut_up(const item &it) const
std::optional< int > try_to_cut_up(Character &p, item &cutter, item_location &cut) const
static constexpr time_duration from_moves(const T t)
Definition: calendar.h:225
uilist: scrolling vertical list menu
Definition: ui.h:232
int ret
Definition: ui.h:525
void addentry(const std::string &txt)
Definition: ui.cpp:1210
void addentry_col(int retval, bool enabled, int key, const std::string &txt, const std::string &column, const std::string &desc="")
Definition: ui.cpp:1244
std::string text
Definition: ui.h:419
std::vector< const item * > items_with(const std::function< bool(const item &)> &filter) const
Definition: visitable.cpp:330
#define debugmsg(...)
Debug message of level D_ERROR and class D_MAIN, also includes the source file name and line,...
Definition: debug.h:69
@ m_info
Definition: enums.h:352
static const itype_id itype_disassembly("disassembly")
static std::vector< std::pair< map_stack::iterator, int > > generate_butcher_stack_display(const std::vector< map_stack::iterator > &its)
Definition: game.cpp:9354
static const quality_id qual_BUTCHER("BUTCHER")
static void add_disassemblables(uilist &menu, const std::vector< std::pair< map_stack::iterator, int >> &stacks, size_t &menu_index)
Definition: game.cpp:9421
static const quality_id qual_CUT_FINE("CUT_FINE")
static void butcher_submenu(const std::vector< map_stack::iterator > &corpses, int index=-1)
Definition: game.cpp:9448
static void add_corpses(uilist &menu, const std::vector< map_stack::iterator > &its, size_t &menu_index)
Definition: game.cpp:9388
static void add_salvagables(uilist &menu, const std::vector< std::pair< map_stack::iterator, int >> &stacks, size_t &menu_index, const salvage_actor &salvage_iuse)
Definition: game.cpp:9400
constexpr int MAX_ITEM_IN_SQUARE
constexpr int PICKUP_RANGE
Items on the map with at most this distance to the player are considered available for crafting,...
void query(bool loop=true, int timeout=-1)
Handle input and update display.
Definition: ui.cpp:1032
void add_msg(std::string msg)
Definition: messages.cpp:997
bool query_yn(const std::string &text)
Definition: output.cpp:811
iuse_actor * get_actor_ptr()
Definition: iuse.h:314

References _, Character::activity, add_corpses(), add_disassemblables(), add_msg(), add_salvagables(), uilist::addentry(), uilist::addentry_col(), Character::assign_activity(), item_stack::begin(), butcher_submenu(), Character::can_disassemble(), Character::controlling_vehicle, Character::crafting_inventory(), debugmsg, Character::disassemble(), Character::disassemble_all(), Creature::disp_name(), item_stack::end(), time_duration::from_moves(), generate_butcher_stack_display(), use_function::get_actor_ptr(), Character::get_crafting_helpers(), Character::get_item_position(), get_player_character, item::get_recursive_disassemble_moves(), recipe_dictionary::get_uncraft(), item::get_usable_item(), item::get_use(), map::has_flag(), Character::has_morale_to_craft(), map::i_at(), ignore_proficiencies, is_hostile_very_close(), visitable::items_with(), itype_disassembly, m, m_info, MAX_ITEM_IN_SQUARE, Character::max_quality(), PICKUP_RANGE, Creature::pos(), qual_BUTCHER, qual_CUT_FINE, uilist::query(), query_yn(), recipe::result(), cata::hash64_detail::ret, uilist::ret, map::sees_some_items(), item_stack::size(), ret_val_common::success(), player_activity::targets, uilist::text, TFLAG_SEALED, recipe::time_to_craft_moves(), salvage_actor::time_to_cut_up(), to_string_clipped(), salvage_actor::try_to_cut_up(), calendar::turn, u, and salvage_actor::valid_to_cut_up().

Referenced by do_regular_action().

◆ calc_driving_offset()

void game::calc_driving_offset ( vehicle veh = nullptr)

Definition at line 1322 of file game.cpp.

1323 {
1324  if( veh == nullptr || !get_option<bool>( "DRIVING_VIEW_OFFSET" ) ) {
1326  return;
1327  }
1328  const int g_light_level = static_cast<int>( light_level( u.posz() ) );
1329  const int light_sight_range = u.sight_range( g_light_level );
1330  int sight = std::max( veh_lumi( *veh ), light_sight_range );
1331 
1332  // The maximal offset will leave at least this many tiles
1333  // between the PC and the edge of the main window.
1334  static const int border_range = 2;
1335  point max_offset( ( getmaxx( w_terrain ) + 1 ) / 2 - border_range - 1,
1336  ( getmaxy( w_terrain ) + 1 ) / 2 - border_range - 1 );
1337 
1338  // velocity at or below this results in no offset at all
1339  static const float min_offset_vel = 1 * vehicles::vmiph_per_tile;
1340  // velocity at or above this results in maximal offset
1341  const float max_offset_vel = std::min( max_offset.y, max_offset.x ) *
1343  float velocity = veh->velocity;
1344  rl_vec2d offset = veh->move_vec();
1345  if( !veh->skidding && veh->player_in_control( u ) &&
1347  // Use cruise_velocity, but only if
1348  // it is not too different from the actual velocity.
1349  // The actual velocity changes too often (see above slowdown).
1350  // Using it makes would make the offset change far too often.
1351  offset = veh->face_vec();
1352  velocity = veh->cruise_velocity;
1353  }
1354  const float rel_offset = inverse_lerp( min_offset_vel, max_offset_vel, velocity );
1355  // Squeeze into the corners, by making the offset vector longer,
1356  // the PC is still in view as long as both offset.x and
1357  // offset.y are <= 1
1358  if( std::fabs( offset.x ) > std::fabs( offset.y ) && std::fabs( offset.x ) > 0.2 ) {
1359  offset.y /= std::fabs( offset.x );
1360  offset.x = ( offset.x > 0 ) ? +1 : -1;
1361  } else if( std::fabs( offset.y ) > 0.2 ) {
1362  offset.x /= std::fabs( offset.y );
1363  offset.y = offset.y > 0 ? +1 : -1;
1364  }
1365  offset.x *= rel_offset;
1366  offset.y *= rel_offset;
1367  offset.x *= max_offset.x;
1368  offset.y *= max_offset.y;
1369  // [ ----@---- ] sight=6
1370  // [ --@------ ] offset=2
1371  // [ -@------# ] offset=3
1372  // can see sights square in every direction, total visible area is
1373  // (2*sight+1)x(2*sight+1), but the window is only
1374  // getmaxx(w_terrain) x getmaxy(w_terrain)
1375  // The area outside of the window is maxoff (sight-getmax/2).
1376  // If that value is <= 0, the whole visible area fits the window.
1377  // don't apply the view offset at all.
1378  // If the offset is > maxoff, only apply at most maxoff, everything
1379  // above leads to invisible area in front of the car.
1380  // It will display (getmax/2+offset) squares in one direction and
1381  // (getmax/2-offset) in the opposite direction (centered on the PC).
1382  const point maxoff( ( sight * 2 + 1 - getmaxx( w_terrain ) ) / 2,
1383  ( sight * 2 + 1 - getmaxy( w_terrain ) ) / 2 );
1384  if( maxoff.x <= 0 ) {
1385  offset.x = 0;
1386  } else if( offset.x > 0 && offset.x > maxoff.x ) {
1387  offset.x = maxoff.x;
1388  } else if( offset.x < 0 && -offset.x > maxoff.x ) {
1389  offset.x = -maxoff.x;
1390  }
1391  if( maxoff.y <= 0 ) {
1392  offset.y = 0;
1393  } else if( offset.y > 0 && offset.y > maxoff.y ) {
1394  offset.y = maxoff.y;
1395  } else if( offset.y < 0 && -offset.y > maxoff.y ) {
1396  offset.y = -maxoff.y;
1397  }
1398 
1399  // Turn the offset into a vector that increments the offset toward the desired position
1400  // instead of setting it there instantly, should smooth out jerkiness.
1401  const point offset_difference( -driving_view_offset + point( offset.x, offset.y ) );
1402 
1403  const point offset_sign( ( offset_difference.x < 0 ) ? -1 : 1,
1404  ( offset_difference.y < 0 ) ? -1 : 1 );
1405  // Shift the current offset in the direction of the calculated offset by one tile
1406  // per draw event, but snap to calculated offset if we're close enough to avoid jitter.
1407  offset.x = ( std::abs( offset_difference.x ) > 1 ) ?
1408  ( driving_view_offset.x + offset_sign.x ) : offset.x;
1409  offset.y = ( std::abs( offset_difference.y ) > 1 ) ?
1410  ( driving_view_offset.y + offset_sign.y ) : offset.y;
1411 
1412  set_driving_view_offset( point( offset.x, offset.y ) );
1413 }
constexpr float inverse_lerp(const T &min, const T &max, const T &value)
Definition: cata_utility.h:246
int sight_range(float light_level) const override
Returns the player's sight range.
Definition: character.cpp:1237
int posz() const
Definition: creature.h:317
point driving_view_offset
Definition: game.h:1118
catacurses::window w_terrain
Definition: game.h:1108
void set_driving_view_offset(const point &p)
Definition: game.cpp:1415
unsigned char light_level(int zlev) const
Returns coarse number-of-squares of visibility at the current light level.
Definition: game.cpp:4452
rl_vec2d move_vec() const
rl_vec2d face_vec() const
bool skidding
Definition: vehicle.h:2363
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:253
int velocity
Definition: vehicle.h:2276
int cruise_velocity
Definition: vehicle.h:2284
static int veh_lumi(vehicle &veh)
Definition: game.cpp:1304
double abs(std::vector< double > const &params)
double max(std::vector< double > const &params)
double min(std::vector< double > const &params)
int getmaxx(const window &win)
Definition: ncurses_def.cpp:91
int getmaxy(const window &win)
Definition: ncurses_def.cpp:99
quantity< V, U > fabs(quantity< V, U > q)
Definition: units.h:147
constexpr float vmiph_per_tile
Definition: vehicle.h:81
constexpr point point_zero
Definition: point.h:251
int y
Definition: point.h:24
int x
Definition: point.h:23
Definition: line.h:280
float y
Definition: line.h:282
float x
Definition: line.h:281

References abs(), vehicle::cruise_velocity, driving_view_offset, units::fabs(), vehicle::face_vec(), catacurses::getmaxx(), catacurses::getmaxy(), inverse_lerp(), light_level(), max(), min(), vehicle::move_vec(), vehicle::player_in_control(), point, point_zero, Creature::posz(), set_driving_view_offset(), Character::sight_range(), vehicle::skidding, u, veh_lumi(), vehicle::velocity, vehicles::vmiph_per_tile, w_terrain, rl_vec2d::x, point::x, rl_vec2d::y, and point::y.

◆ can_move_furniture()

bool game::can_move_furniture ( tripoint  fdest,
const tripoint dp 
)

Definition at line 11356 of file game.cpp.

11357 {
11358  const bool pulling_furniture = dp.xy() == -u.grab_point.xy();
11359  const bool has_floor = m.has_floor_or_water( fdest );
11360  creature_tracker &creatures = get_creature_tracker();
11361  bool is_ramp_or_road = m.has_flag( ter_furn_flag::TFLAG_RAMP_DOWN, fdest ) ||
11364  return m.passable( fdest ) &&
11365  creatures.creature_at<npc>( fdest ) == nullptr &&
11366  creatures.creature_at<monster>( fdest ) == nullptr &&
11367  ( !pulling_furniture || is_empty( u.pos() + dp ) ) &&
11368  ( !has_floor || m.has_flag( ter_furn_flag::TFLAG_FLAT, fdest ) ||
11369  is_ramp_or_road ) &&
11370  !m.has_furn( fdest ) &&
11371  !m.veh_at( fdest ) &&
11372  ( !has_floor || m.tr_at( fdest ).is_null() );
11373 }
tripoint grab_point
Definition: character.h:592
T * creature_at(const tripoint &p, bool allow_hallucination=false)
Returns the Creature at the given location.
friend creature_tracker & get_creature_tracker()
Definition: game.cpp:13827
bool is_empty(const tripoint &p)
Returns true if there is no player, NPC, or monster on the tile and move_cost > 0.
Definition: game.cpp:5506
bool has_furn(const tripoint &p) const
Definition: map.cpp:1712
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:6213
bool has_floor_or_water(const tripoint &p) const
Definition: map.cpp:2703
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1316
bool passable(const tripoint &p) const
Definition: map.cpp:2472
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:366
constexpr point xy() const
Definition: point.h:202

References creature_tracker::creature_at(), get_creature_tracker, Character::grab_point, map::has_flag(), map::has_floor_or_water(), map::has_furn(), is_empty(), trap::is_null(), m, map::passable(), Creature::pos(), TFLAG_FLAT, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_ROAD, map::tr_at(), u, map::veh_at(), and tripoint::xy().

Referenced by grabbed_furn_move(), and grabbed_furn_move_time().

◆ cancel_activity_or_ignore_query()

bool game::cancel_activity_or_ignore_query ( distraction_type  type,
const std::string &  text 
)

Asks if the player wants to cancel their activity and if so cancels it.

Additionally checks if the player wants to ignore further distractions.

Definition at line 1455 of file game.cpp.

1456 {
1457  if( u.has_distant_destination() ) {
1458  if( cancel_auto_move( u, text ) ) {
1459  return true;
1460  } else {
1462  return false;
1463  }
1464  }
1466  return false;
1467  }
1468  const bool force_uc = get_option<bool>( "FORCE_CAPITAL_YN" );
1469  const auto &allow_key = force_uc ? input_context::disallow_lower_case_or_non_modified_letters
1471 
1472  const std::string &action = query_popup()
1474  .context( "CANCEL_ACTIVITY_OR_IGNORE_QUERY" )
1475  .message( force_uc && !is_keycode_mode_supported() ?
1476  pgettext( "cancel_activity_or_ignore_query",
1477  "<color_light_red>%s %s (Case Sensitive)</color>" ) :
1478  pgettext( "cancel_activity_or_ignore_query",
1479  "<color_light_red>%s %s</color>" ),
1480  text, u.activity.get_stop_phrase() )
1481  .option( "YES", allow_key )
1482  .option( "NO", allow_key )
1483  .option( "MANAGER", allow_key )
1484  .option( "IGNORE", allow_key )
1485  .query()
1486  .action;
1487 
1488  if( action == "YES" ) {
1489  u.cancel_activity();
1490  return true;
1491  }
1492  if( action == "IGNORE" ) {
1494  for( player_activity &activity : u.backlog ) {
1495  activity.ignore_distraction( type );
1496  }
1497  }
1498  if( action == "MANAGER" ) {
1499  u.cancel_activity();
1501  return true;
1502  }
1503 
1505  refresh_display();
1506 
1507  return false;
1508 }
std::vector< tripoint_bub_ms > & get_auto_move_route()
void set_destination(const std::vector< tripoint_bub_ms > &route, const player_activity &new_destination_activity=player_activity())
void cancel_activity()
Definition: character.cpp:8983
std::list< player_activity > backlog
Definition: character.h:2710
bool has_distant_destination() const
static bool disallow_lower_case_or_non_modified_letters(const input_event &evt)
static bool allow_all_keys(const input_event &evt)
std::string get_stop_phrase() const
bool is_distraction_ignored(distraction_type) const
void ignore_distraction(distraction_type)
UI class for displaying messages or querying player input with popups.
Definition: popup.h:36
query_popup & context(const std::string &cat)
Specify the input context.
Definition: popup.cpp:153
query_popup & option(const std::string &opt)
Specify an action as an option.
Definition: popup.cpp:160
result query()
Query until a valid action or an error happens and return the result.
Definition: popup.cpp:403
query_popup & preferred_keyboard_mode(keyboard_mode mode)
Specify the desired keyboard mode.
Definition: popup.cpp:222
query_popup & message(const std::string &fmt, Args &&... args)
Specify the query message.
Definition: popup.h:89
@ action
Definition: dialogue.h:43
distraction_manager::distraction_manager_gui & get_distraction_manager()
static bool cancel_auto_move(Character &you, const std::string &text)
Definition: game.cpp:1441
static const activity_id ACT_TRAVELLING("ACT_TRAVELLING")
bool is_keycode_mode_supported()
Definition: input.cpp:63
void redraw()
Invalidate the top window and redraw all invalidated windows.
Definition: ui_manager.cpp:504
void refresh_display()
Make changes made to the display visible to the user immediately.
std::string action
Definition: popup.h:66
#define pgettext(STRING1, STRING2)
Definition: translations.h:92

References ACT_TRAVELLING, action, query_popup::result::action, Character::activity, input_context::allow_all_keys(), Character::backlog, Character::cancel_activity(), cancel_auto_move(), query_popup::context(), input_context::disallow_lower_case_or_non_modified_letters(), Character::get_auto_move_route(), get_distraction_manager(), player_activity::get_stop_phrase(), Character::has_distant_destination(), player_activity::ignore_distraction(), player_activity::is_distraction_ignored(), is_keycode_mode_supported(), keycode, query_popup::message(), query_popup::option(), pgettext, query_popup::preferred_keyboard_mode(), query_popup::query(), ui_manager::redraw(), refresh_display(), Character::set_destination(), distraction_manager::distraction_manager_gui::show(), type, and u.

Referenced by mon_info_update().

◆ cancel_activity_query()

bool game::cancel_activity_query ( const std::string &  text)

Asks if the player wants to cancel their activity, and if so cancels it.

Definition at line 1551 of file game.cpp.

1552 {
1553  if( u.has_destination() ) {
1554  if( cancel_auto_move( u, text ) ) {
1555  return true;
1556  } else if( u.has_distant_destination() ) {
1558  return false;
1559  }
1560  }
1561  if( !u.activity ) {
1562  return false;
1563  }
1564  g->invalidate_main_ui_adaptor();
1565  if( query_yn( "%s %s", text, u.activity.get_stop_phrase() ) ) {
1566  if( u.activity.id() == ACT_TRAIN_TEACHER ) {
1567  for( npc &n : all_npcs() ) {
1568  // Also cancel activities for students
1569  for( const int st_id : u.activity.values ) {
1570  if( n.getID().get_value() == st_id ) {
1571  n.cancel_activity();
1572  }
1573  }
1574  }
1576  } else if( u.activity.id() == ACT_TRAIN ) {
1577  for( npc &n : all_npcs() ) {
1578  // If the player is the only student, cancel the teacher's activity
1579  if( n.getID().get_value() == u.activity.index && n.activity.values.size() == 1 ) {
1580  n.cancel_activity();
1581  }
1582  }
1583  }
1584  u.cancel_activity();
1585  u.clear_destination();
1587  return true;
1588  }
1589  return false;
1590 }
void clear_destination()
bool has_destination() const
void resume_backlog_activity()
Definition: character.cpp:9019
bool remove_effect(const efftype_id &eff_id, const bodypart_id &bp)
Removes a listed effect.
Definition: creature.cpp:1722
npc_range all_npcs()
Same as all_creatures but iterators only over npcs.
Definition: game.cpp:13233
const activity_id & id() const
std::vector< int > values
static const activity_id ACT_TRAIN_TEACHER("ACT_TRAIN_TEACHER")
static const activity_id ACT_TRAIN("ACT_TRAIN")
static const efftype_id effect_asked_to_train("asked_to_train")

References ACT_TRAIN, ACT_TRAIN_TEACHER, ACT_TRAVELLING, Character::activity, all_npcs(), Character::cancel_activity(), cancel_auto_move(), Character::clear_destination(), effect_asked_to_train, g, Character::get_auto_move_route(), player_activity::get_stop_phrase(), Character::has_destination(), Character::has_distant_destination(), player_activity::id(), player_activity::index, query_yn(), Creature::remove_effect(), Character::resume_backlog_activity(), Character::set_destination(), u, and player_activity::values.

◆ catch_a_monster()

void game::catch_a_monster ( monster fish,
const tripoint pos,
Character p,
const time_duration catch_duration 
)

Picks and spawns a random fish from the remaining fish list when a fish is caught.

Definition at line 1427 of file game.cpp.

1429 {
1430  //spawn the corpse, rotten by a part of the duration
1432  catch_duration ) ) );
1433  if( u.sees( pos ) ) {
1434  u.add_msg_if_player( m_good, _( "You caught a %s." ), fish->type->nname() );
1435  }
1436  //quietly kill the caught
1437  fish->no_corpse_quiet = true;
1438  fish->die( p );
1439 }
time_duration rng(time_duration lo, time_duration hi)
Definition: calendar.cpp:779
bool sees(const tripoint &t, bool is_avatar=false, int range_mod=0) const override
void add_msg_if_player(const std::string &msg) const override
Definition: character.cpp:856
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:604
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Definition: map.cpp:5177
bool no_corpse_quiet
Definition: monster.h:554
void die(Creature *killer) override
Empty function.
Definition: monster.cpp:2742
const mtype * type
Definition: monster.h:550
@ m_good
Definition: enums.h:347
constexpr double pos(double, double r)
mtype_id id
Definition: mtype.h:301
std::string nname(unsigned int quantity=1) const
Definition: mtype.cpp:330

References _, map::add_item_or_charges(), Character::add_msg_if_player(), monster::die(), mtype::id, m, m_good, item::make_corpse(), mtype::nname(), monster::no_corpse_quiet, math_opers::pos(), rng(), Character::sees(), calendar::turn, monster::type, and u.

◆ chat()

void game::chat ( )
private

Definition at line 797 of file npctalk.cpp.

798 {
799  Character &player_character = get_player_character();
800  int volume = player_character.get_shout_volume();
801 
802  const std::vector<Creature *> available = get_creatures_if( [&]( const Creature & guy ) {
803  // TODO: Get rid of the z-level check when z-level vision gets "better"
804  return ( guy.is_npc() || ( guy.is_monster() &&
806  !guy.as_monster()->type->chat_topics.empty() ) ) && u.posz() == guy.posz() && u.sees( guy.pos() ) &&
807  rl_dist( u.pos(), guy.pos() ) <= SEEX * 2;
808  } );
809  const int available_count = available.size();
810  const std::vector<npc *> followers = get_npcs_if( [&]( const npc & guy ) {
811  return guy.is_player_ally() && guy.is_following() && guy.can_hear( u.pos(), volume );
812  } );
813  const int follower_count = followers.size();
814  const std::vector<npc *> guards = get_npcs_if( [&]( const npc & guy ) {
815  return guy.mission == NPC_MISSION_GUARD_ALLY &&
816  guy.companion_mission_role_id != "FACTION_CAMP" &&
817  guy.can_hear( u.pos(), volume );
818  } );
819  const int guard_count = guards.size();
820 
821  const std::vector<npc *> available_for_activities = get_npcs_if( [&]( const npc & guy ) {
822  return guy.is_player_ally() && guy.can_hear( u.pos(), volume ) &&
823  guy.companion_mission_role_id != "FACTION CAMP";
824  } );
825  const int available_for_activities_count = available_for_activities.size();
826 
827  if( player_character.has_trait( trait_PROF_FOODP ) &&
828  !( player_character.is_wearing( itype_foodperson_mask ) ||
829  player_character.is_wearing( itype_foodperson_mask_on ) ) ) {
830  add_msg( m_warning, _( "You can't speak without your face!" ) );
831  return;
832  }
833  std::vector<vehicle *> animal_vehicles;
834  std::vector<vehicle *> following_vehicles;
835  std::vector<vehicle *> magic_vehicles;
836  std::vector<vehicle *> magic_following_vehicles;
837  for( wrapped_vehicle &veh : get_map().get_vehicles() ) {
838  vehicle *&v = veh.v;
839  if( v->has_engine_type( fuel_type_animal, false ) &&
840  v->is_owned_by( player_character ) ) {
841  animal_vehicles.push_back( v );
842  if( v->is_following ) {
843  following_vehicles.push_back( v );
844  }
845  }
846  if( v->magic ) {
847  for( const vpart_reference &vp : v->get_all_parts() ) {
848  const vpart_info &vpi = vp.info();
849  if( vpi.has_flag( "MAGIC_FOLLOW" ) ) {
850  magic_vehicles.push_back( v );
851  if( v->is_following ) {
852  magic_following_vehicles.push_back( v );
853  }
854  break;
855  }
856  }
857  }
858  }
859 
860  uilist nmenu;
861  nmenu.text = std::string( _( "What do you want to do?" ) );
862 
863  if( !available.empty() ) {
864  const Creature *guy = available.front();
865  std::string title;
866  if( guy->is_npc() ) {
867  title = guy->as_npc()->name_and_activity();
868  } else if( guy->is_monster() ) {
869  title = guy->as_monster()->disp_name();
870  }
871  nmenu.addentry( NPC_CHAT_TALK, true, 't', available_count == 1 ?
872  string_format( _( "Talk to %s" ), title ) :
873  _( "Talk to…" ) );
874  }
875 
876  if( !available_for_activities.empty() ) {
877  const Creature *guy = available_for_activities.front();
878  std::string title;
879  if( guy->is_npc() ) {
880  title = guy->as_npc()->name_and_activity();
881  } else if( guy->is_monster() ) {
882  title = guy->as_monster()->disp_name();
883  }
884  nmenu.addentry( NPC_CHAT_ACTIVITIES, true, 'A', available_for_activities_count == 1 ?
885  string_format( _( "Tell %s to work on…" ), title ) :
886  _( "Tell someone to work on…" )
887  );
888  }
889 
890  nmenu.addentry( NPC_CHAT_YELL, true, 'a', _( "Yell" ) );
891  nmenu.addentry( NPC_CHAT_SENTENCE, true, 'b', _( "Yell a sentence" ) );
892  nmenu.addentry( NPC_CHAT_EMOTE, true, 'E', _( "Emote" ) );
893  if( !animal_vehicles.empty() ) {
894  nmenu.addentry( NPC_CHAT_ANIMAL_VEHICLE_FOLLOW, true, 'F',
895  _( "Whistle at your animals pulling vehicles to follow you." ) );
896  }
897  if( !magic_vehicles.empty() ) {
899  _( "Utter a magical command that will order your magical vehicles to follow you." ) );
900  }
901  if( !magic_following_vehicles.empty() ) {
903  _( "Utter a magical command that will order your magical vehicles to stop following you." ) );
904  }
905  if( !following_vehicles.empty() ) {
907  _( "Whistle at your animals pulling vehicles to stop following you." ) );
908  }
909  if( !guards.empty() ) {
910  nmenu.addentry( NPC_CHAT_FOLLOW, true, 'f', guard_count == 1 ?
911  string_format( _( "Tell %s to follow" ), guards.front()->get_name() ) :
912  _( "Tell someone to follow…" )
913  );
914  }
915  if( !followers.empty() ) {
916  bool enable_seminar = !player_character.has_effect( effect_asked_to_train );
917  nmenu.addentry( NPC_CHAT_START_SEMINAR, enable_seminar, 'T',
918  enable_seminar ? _( "Start a training seminar" ) :
919  _( "Start a training seminar (You've already taught enough for now)" ) );
920  nmenu.addentry( NPC_CHAT_GUARD, true, 'g', follower_count == 1 ?
921  string_format( _( "Tell %s to guard" ), followers.front()->get_name() ) :
922  _( "Tell someone to guard…" )
923  );
924  nmenu.addentry( NPC_CHAT_MOVE_TO_POS, true, 'G',
925  follower_count == 1 ? string_format( _( "Tell %s to move to location" ),
926  followers.front()->get_name() ) : _( "Tell someone to move to location…" ) );
927  nmenu.addentry( NPC_CHAT_AWAKE, true, 'w', _( "Tell everyone on your team to wake up" ) );
928  nmenu.addentry( NPC_CHAT_MOUNT, true, 'M', _( "Tell everyone on your team to mount up" ) );
929  nmenu.addentry( NPC_CHAT_DISMOUNT, true, 'm', _( "Tell everyone on your team to dismount" ) );
930  nmenu.addentry( NPC_CHAT_DANGER, true, 'D',
931  _( "Tell everyone on your team to prepare for danger" ) );
932  nmenu.addentry( NPC_CHAT_CLEAR_OVERRIDES, true, 'r',
933  _( "Tell everyone on your team to relax (Clear Overrides)" ) );
934  nmenu.addentry( NPC_CHAT_ORDERS, true, 'o', _( "Tell everyone on your team to temporarily…" ) );
935  }
936  std::string message;
937  std::string yell_msg;
938  std::string emote_msg;
939  bool is_order = true;
940  nmenu.query();
941 
942  if( nmenu.ret < 0 ) {
943  return;
944  }
945 
946  switch( nmenu.ret ) {
947  case NPC_CHAT_TALK: {
948  const int npcselect = creature_select_menu( available, _( "Talk to whom?" ), false );
949  if( npcselect < 0 ) {
950  return;
951  }
952  get_avatar().talk_to( get_talker_for( *available[npcselect] ) );
953  break;
954  }
955  case NPC_CHAT_YELL:
956  is_order = false;
957  message = _( "loudly." );
958  break;
959  case NPC_CHAT_SENTENCE: {
960  std::string popupdesc = _( "Enter a sentence to yell" );
962  popup.title( _( "Yell a sentence" ) )
963  .width( 64 )
964  .description( popupdesc )
965  .identifier( "sentence" )
966  .max_length( 128 )
967  .query();
968  yell_msg = popup.text();
969  is_order = false;
970  break;
971  }
972  case NPC_CHAT_EMOTE: {
973  std::string popupdesc =
974  _( "What do you want to emote? (This will have no in-game effect!)" );
976  popup.title( _( "Emote" ) )
977  .width( 64 )
978  .description( popupdesc )
979  .identifier( "sentence" )
980  .max_length( 128 )
981  .query();
982  emote_msg = popup.text();
983  is_order = false;
984  break;
985  }
986  case NPC_CHAT_START_SEMINAR: {
987  const std::string &t = training_select_menu( player_character,
988  _( "What would you like to teach?" ) );
989  if( t.empty() ) {
990  return;
991  }
992  int id_type = -1;
993  std::vector<Character *> clist( followers.begin(), followers.end() );
994  const std::string query_str = _( "Who should participate in the training seminar?" );
995  std::vector<int> selected;
996  skill_id sk( t );
997  if( sk.is_valid() ) {
998  selected = npcs_select_menu( clist, query_str, [&]( const Character * n ) {
999  return !n ||
1000  n->get_knowledge_level( sk ) >= static_cast<int>( player_character.get_skill_level( sk ) );
1001  } );
1002  id_type = 0;
1003  }
1004  matype_id ma( t );
1005  if( ma.is_valid() ) {
1006  selected = npcs_select_menu( clist, query_str, [&]( const Character * n ) {
1007  return !n || n->has_martialart( ma );
1008  } );
1009  id_type = 1;
1010  }
1011  proficiency_id pr( t );
1012  if( pr.is_valid() ) {
1013  selected = npcs_select_menu( clist, query_str, [&]( const Character * n ) {
1014  return !n || n->has_proficiency( pr );
1015  } );
1016  id_type = 2;
1017  }
1018  spell_id sp( t );
1019  if( sp.is_valid() ) {
1020  selected = npcs_select_menu( clist, query_str, [&]( const Character * n ) {
1021  return !n || ( n->magic->knows_spell( sp ) &&
1022  n->magic->get_spell( sp ).get_level() >= player_character.magic->get_spell( sp ).get_level() );
1023  } );
1024  id_type = 3;
1025  }
1026  if( selected.empty() ) {
1027  return;
1028  }
1029  std::vector<Character *> to_train;
1030  for( int i : selected ) {
1031  if( followers[i] ) {
1032  to_train.push_back( followers[i] );
1033  }
1034  }
1036  d.skill = id_type == 0 ? sk : skill_id();
1037  d.style = id_type == 1 ? ma : matype_id();
1038  d.prof = id_type == 2 ? pr : proficiency_id();
1039  d.spell = id_type == 3 ? sp : spell_id();
1040  talk_function::start_training_gen( player_character, to_train, d );
1041  break;
1042  }
1043  case NPC_CHAT_GUARD: {
1044  const int npcselect = npc_select_menu( followers, _( "Who should guard here?" ) );
1045  if( npcselect < 0 ) {
1046  return;
1047  }
1048  if( npcselect == follower_count ) {
1049  for( npc *them : followers ) {
1050  talk_function::assign_guard( *them );
1051  }
1052  yell_msg = _( "Everyone guard here!" );
1053  } else {
1054  talk_function::assign_guard( *followers[npcselect] );
1055  yell_msg = string_format( _( "Guard here, %s!" ), followers[npcselect]->get_name() );
1056  }
1057  break;
1058  }
1059  case NPC_CHAT_MOVE_TO_POS: {
1060  const int npcselect = npc_select_menu( followers, _( "Who should move?" ) );
1061  if( npcselect < 0 ) {
1062  return;
1063  }
1064 
1065  map &here = get_map();
1066  std::optional<tripoint> p = look_around();
1067 
1068  if( !p ) {
1069  return;
1070  }
1071 
1072  if( here.impassable( tripoint( *p ) ) ) {
1073  add_msg( m_info, _( "This destination can't be reached." ) );
1074  return;
1075  }
1076 
1077  if( npcselect == follower_count ) {
1078  for( npc *them : followers ) {
1079  them->goto_to_this_pos = here.getglobal( *p );
1080  }
1081  yell_msg = _( "Everyone move there!" );
1082  } else {
1083  followers[npcselect]->goto_to_this_pos = here.getglobal( *p );
1084  yell_msg = string_format( _( "Move there, %s!" ), followers[npcselect]->get_name() );
1085  }
1086  break;
1087  }
1088  case NPC_CHAT_FOLLOW: {
1089  const int npcselect = npc_select_menu( guards, _( "Who should follow you?" ) );
1090  if( npcselect < 0 ) {
1091  return;
1092  }
1093  if( npcselect == guard_count ) {
1094  for( npc *them : guards ) {
1095  talk_function::stop_guard( *them );
1096  }
1097  yell_msg = _( "Everyone follow me!" );
1098  } else {
1099  talk_function::stop_guard( *guards[npcselect] );
1100  yell_msg = string_format( _( "Follow me, %s!" ), guards[npcselect]->get_name() );
1101  }
1102  break;
1103  }
1104  case NPC_CHAT_AWAKE:
1105  for( npc *them : followers ) {
1106  talk_function::wake_up( *them );
1107  }
1108  yell_msg = _( "Stay awake!" );
1109  break;
1110  case NPC_CHAT_MOUNT:
1111  for( npc *them : followers ) {
1112  if( them->has_effect( effect_riding ) || them->is_hallucination() ) {
1113  continue;
1114  }
1115  talk_function::find_mount( *them );
1116  }
1117  yell_msg = _( "Mount up!" );
1118  break;
1119  case NPC_CHAT_DISMOUNT:
1120  for( npc *them : followers ) {
1121  if( them->has_effect( effect_riding ) ) {
1122  them->npc_dismount();
1123  }
1124  }
1125  yell_msg = _( "Dismount!" );
1126  break;
1127  case NPC_CHAT_DANGER:
1128  for( npc *them : followers ) {
1129  them->rules.set_danger_overrides();
1130  }
1131  yell_msg = _( "We're in danger. Stay awake, stay close, don't go wandering off, "
1132  "and don't open any doors." );
1133  break;
1135  for( npc *p : followers ) {
1137  }
1138  yell_msg = _( "As you were." );
1139  break;
1140  case NPC_CHAT_ORDERS:
1141  npc_temp_orders_menu( followers );
1142  break;
1145  break;
1148  break;
1151  break;
1154  break;
1155  case NPC_CHAT_ACTIVITIES: {
1156  const int activity = npc_activities_menu();
1157 
1158  std::vector<int> npcs_selected;
1159 
1160  if( available_for_activities_count == 1 ) {
1161  npcs_selected.push_back( 0 );
1162  } else {
1163  std::vector<Character *> clist( available_for_activities.begin(), available_for_activities.end() );
1164  npcs_selected = npcs_select_menu( clist, _( "Who should we assign?" ), nullptr );
1165  }
1166 
1167  for( int i : npcs_selected ) {
1168 
1169  npc *selected_npc = available_for_activities[i];
1170 
1171  switch( activity ) {
1173  talk_function::sort_loot( *selected_npc );
1174  break;
1175  }
1177  talk_function::do_butcher( *selected_npc );
1178  break;
1179  }
1181  talk_function::do_chop_plank( *selected_npc );
1182  break;
1183  }
1185  talk_function::do_chop_trees( *selected_npc );
1186  break;
1187  }
1189  talk_function::do_construction( *selected_npc );
1190  break;
1191  }
1193  talk_function::do_craft( *selected_npc );
1194  break;
1195  }
1197  talk_function::do_disassembly( *selected_npc );
1198  break;
1199  }
1201  talk_function::do_farming( *selected_npc );
1202  break;
1203  }
1205  talk_function::do_fishing( *selected_npc );
1206  break;
1207  }
1209  talk_function::do_read_repeatedly( *selected_npc );
1210  break;
1211  }
1213  talk_function::do_mining( *selected_npc );
1214  break;
1215  }
1217  talk_function::do_mopping( *selected_npc );
1218  break;
1219  }
1221  talk_function::do_vehicle_deconstruct( *selected_npc );
1222  break;
1223  }
1225  talk_function::do_vehicle_repair( *selected_npc );
1226  break;
1227  }
1229  talk_function::revert_activity( *selected_npc );
1230  break;
1231  }
1232  default:
1233  break;
1234  }
1235  }
1236  break;
1237  }
1238  default:
1239  return;
1240  }
1241 
1242  if( !yell_msg.empty() ) {
1243  message = string_format( _( "\"%s\"" ), yell_msg );
1244  }
1245  if( !message.empty() ) {
1246  add_msg( _( "You yell %s" ), message );
1247  u.shout( string_format( _( "%s yelling %s" ), u.disp_name(), message ), is_order );
1248  }
1249  if( !emote_msg.empty() ) {
1250  add_msg( emote_msg );
1251  }
1252 
1253  u.mod_moves( -u.get_speed() );
1254 }
std::unique_ptr< talker > get_talker_for(avatar &me)
Definition: avatar.cpp:1795
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Returns either "you" or the player's name.
Definition: character.cpp:829
int get_knowledge_level(const skill_id &ident) const
Definition: character.cpp:3441
bool is_wearing(const itype_id &it) const
Returns true if the player is wearing the item.
bool has_proficiency(const proficiency_id &prof) const
void shout(std::string msg="", bool order=false)
Definition: character.cpp:7450
float get_skill_level(const skill_id &ident) const
Definition: character.cpp:3428
bool can_hear(const tripoint &source, int volume) const
bool has_martialart(const matype_id &m) const
Definition: character.cpp:697
int get_speed() const override
Definition: character.cpp:4192
pimpl< known_magic > magic
Definition: character.h:2485
int get_shout_volume() const
Definition: character.cpp:7413
virtual bool is_monster() const
Definition: creature.h:271
virtual npc * as_npc()
Definition: creature.h:286
bool has_effect(const efftype_id &eff_id, const bodypart_id &bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1770
void mod_moves(int nmoves)
Definition: creature.cpp:2008
virtual monster * as_monster()
Definition: creature.h:292
virtual bool is_npc() const
Definition: creature.h:268
void talk_to(std::unique_ptr< talker > talk_with, bool radio_contact=false, bool is_computer=false, bool is_not_conversation=false)
Definition: npctalk.cpp:1358
std::optional< tripoint > look_around()
Definition: game.cpp:7639
std::vector< Creature * > get_creatures_if(const std::function< bool(const Creature &)> &pred)
Returns all creatures matching a predicate.
Definition: game.cpp:13130
friend map & get_map()
Definition: game.cpp:13822
Manage and cache data about a part of the map.
Definition: map.h:346
bool impassable(const tripoint &p) const
Definition: map.cpp:2462
tripoint_abs_ms getglobal(const tripoint &p) const
Definition: map.cpp:9625
bool has_flag(const mon_flag_id &f) const final
Definition: monster.cpp:1202
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:775
std::string companion_mission_role_id
Definition: npc.h:1393
npc_mission mission
Definition: npc.h:1400
std::string name_and_activity() const
Definition: npc.cpp:3771
bool is_player_ally() const
Definition: npc.cpp:2297
bool is_following() const
Definition: npc.cpp:2327
A vehicle as a whole with all its components.
Definition: vehicle.h:802
bool is_owned_by(const Character &c, bool available_to_take=false) const
Definition: vehicle.cpp:4644
bool is_following
Definition: vehicle.h:2348
vehicle_part_range get_all_parts() const
Yields a range containing all parts (including broken ones) that can be iterated over.
Definition: vehicle.cpp:8119
bool magic
Definition: vehicle.h:2219
bool has_engine_type(const itype_id &ft, bool enabled) const
Definition: vehicle.cpp:957
bool has_flag(const std::string &flag) const
Definition: veh_type.h:256
This is a wrapper over a vehicle pointer and a reference to a part of it.
int rl_dist(const coords::coord_point< Point, Origin, Scale, LhsInBounds > &loc1, const coords::coord_point< Point, Origin, Scale, RhsInBounds > &loc2)
Definition: coordinates.h:769
@ m_warning
Definition: enums.h:351
constexpr int SEEX
mon_flag_id mon_flag_CONVERSATION
Definition: mtype.cpp:65
static std::string message
Definition: mapgen.cpp:632
@ title
Definition: music.h:14
void do_mopping(npc &)
void start_training_gen(Character &teacher, std::vector< Character * > &students, teach_domain &d)
void do_chop_trees(npc &)
void wake_up(npc &)
void do_farming(npc &)
void find_mount(npc &)
void do_vehicle_deconstruct(npc &)
void do_craft(npc &)
void revert_activity(npc &)
void sort_loot(npc &)
void clear_overrides(npc &p)
void do_construction(npc &)
void do_vehicle_repair(npc &)
void do_read_repeatedly(npc &)
void do_disassembly(npc &p)
void do_fishing(npc &)
void do_chop_plank(npc &)
void stop_guard(npc &)
void assign_guard(npc &)
void do_mining(npc &)
void do_butcher(npc &)
quantity< int, volume_in_milliliter_tag > volume
Definition: units_fwd.h:17
@ NPC_MISSION_GUARD_ALLY
Definition: npc.h:180
static const efftype_id effect_riding("riding")
static const trait_id trait_PROF_FOODP("PROF_FOODP")
static const itype_id itype_foodperson_mask("foodperson_mask")
std::vector< int > npcs_select_menu(const std::vector< Character * > &npc_list, const std::string &prompt, const std::function< bool(const Character *)> &exclude_func)
Definition: npctalk.cpp:536
static int npc_select_menu(const std::vector< npc * > &npc_list, const std::string &prompt, const bool everyone=true)
Definition: npctalk.cpp:472
static void tell_magic_veh_stop_following()
Definition: npctalk.cpp:780
static void tell_veh_stop_following()
Definition: npctalk.cpp:740
static void assign_veh_to_follow()
Definition: npctalk.cpp:752
static void npc_temp_orders_menu(const std::vector< npc * > &npc_list)
Definition: npctalk.cpp:623
static const itype_id itype_foodperson_mask_on("foodperson_mask_on")
static const itype_id fuel_type_animal("animal")
static int npc_activities_menu()
Definition: npctalk.cpp:711
static int creature_select_menu(const std::vector< Creature * > &talker_list, const std::string &prompt, const bool everyone=true)
Definition: npctalk.cpp:502
static std::string training_select_menu(const Character &c, const std::string &prompt)
Definition: npctalk.cpp:577
@ NPC_CHAT_ACTIVITIES_READ_REPEATEDLY
Definition: npctalk.cpp:463
@ NPC_CHAT_ACTIVITIES_CHOP_TREES
Definition: npctalk.cpp:455
@ NPC_CHAT_ACTIVITIES_CRAFT
Definition: npctalk.cpp:457
@ NPC_CHAT_MOUNT
Definition: npctalk.cpp:436
@ NPC_CHAT_ACTIVITIES_FISHING
Definition: npctalk.cpp:460
@ NPC_CHAT_ACTIVITIES_CHOP_PLANKS
Definition: npctalk.cpp:454
@ NPC_CHAT_COMMAND_MAGIC_VEHICLE_STOP_FOLLOW
Definition: npctalk.cpp:450
@ NPC_CHAT_ACTIVITIES_CONSTRUCTION
Definition: npctalk.cpp:456
@ NPC_CHAT_YELL
Definition: npctalk.cpp:428
@ NPC_CHAT_ACTIVITIES_FARMING
Definition: npctalk.cpp:459
@ NPC_CHAT_START_SEMINAR
Definition: npctalk.cpp:430
@ NPC_CHAT_ACTIVITIES_UNASSIGN
Definition: npctalk.cpp:466
@ NPC_CHAT_ACTIVITIES_VEHICLE_REPAIR
Definition: npctalk.cpp:465
@ NPC_CHAT_ACTIVITIES
Definition: npctalk.cpp:451
@ NPC_CHAT_FOLLOW
Definition: npctalk.cpp:434
@ NPC_CHAT_GUARD
Definition: npctalk.cpp:432
@ NPC_CHAT_DISMOUNT
Definition: npctalk.cpp:437
@ NPC_CHAT_ACTIVITIES_DISASSEMBLY
Definition: npctalk.cpp:458
@ NPC_CHAT_ANIMAL_VEHICLE_FOLLOW
Definition: npctalk.cpp:447
@ NPC_CHAT_EMOTE
Definition: npctalk.cpp:429
@ NPC_CHAT_ORDERS
Definition: npctalk.cpp:439
@ NPC_CHAT_SENTENCE
Definition: npctalk.cpp:431
@ NPC_CHAT_CLEAR_OVERRIDES
Definition: npctalk.cpp:446
@ NPC_CHAT_DANGER
Definition: npctalk.cpp:438
@ NPC_CHAT_ACTIVITIES_MINING
Definition: npctalk.cpp:461
@ NPC_CHAT_ACTIVITIES_MOPPING
Definition: npctalk.cpp:462
@ NPC_CHAT_MOVE_TO_POS
Definition: npctalk.cpp:433
@ NPC_CHAT_ACTIVITIES_VEHICLE_DECONSTRUCTION
Definition: npctalk.cpp:464
@ NPC_CHAT_AWAKE
Definition: npctalk.cpp:435
@ NPC_CHAT_ANIMAL_VEHICLE_STOP_FOLLOW
Definition: npctalk.cpp:448
@ NPC_CHAT_TALK
Definition: npctalk.cpp:427
@ NPC_CHAT_ACTIVITIES_BUTCHERY
Definition: npctalk.cpp:453
@ NPC_CHAT_ACTIVITIES_MOVE_LOOT
Definition: npctalk.cpp:452
@ NPC_CHAT_COMMAND_MAGIC_VEHICLE_FOLLOW
Definition: npctalk.cpp:449
static const efftype_id effect_asked_to_train("asked_to_train")
static void tell_magic_veh_to_follow()
Definition: npctalk.cpp:763
int popup(const std::string &text, PopupFlags flags)
Definition: output.cpp:912
std::vector< std::string > chat_topics
Definition: mtype.h:349
proficiency_id prof
Definition: npctalk.h:20

References _, add_msg(), uilist::addentry(), Creature::as_monster(), Creature::as_npc(), talk_function::assign_guard(), assign_veh_to_follow(), available, mtype::chat_topics, talk_function::clear_overrides(), creature_select_menu(), Character::disp_name(), monster::disp_name(), talk_function::do_butcher(), talk_function::do_chop_plank(), talk_function::do_chop_trees(), talk_function::do_construction(), talk_function::do_craft(), talk_function::do_disassembly(), talk_function::do_farming(), talk_function::do_fishing(), talk_function::do_mining(), talk_function::do_mopping(), talk_function::do_read_repeatedly(), talk_function::do_vehicle_deconstruct(), talk_function::do_vehicle_repair(), effect_asked_to_train, effect_riding, talk_function::find_mount(), fuel_type_animal, vehicle::get_all_parts(), get_avatar, get_creatures_if(), Character::get_knowledge_level(), get_map, get_npcs_if(), get_player_character, Character::get_shout_volume(), Character::get_skill_level(), Character::get_speed(), get_talker_for(), map::getglobal(), Creature::has_effect(), vehicle::has_engine_type(), monster::has_flag(), vpart_info::has_flag(), Character::has_martialart(), Character::has_proficiency(), Character::has_trait(), map::impassable(), vehicle::is_following, Creature::is_monster(), Creature::is_npc(), vehicle::is_owned_by(), string_id< T >::is_valid(), Character::is_wearing(), itype_foodperson_mask, itype_foodperson_mask_on, look_around(), m_info, m_warning, Character::magic, vehicle::magic, matype_id, mapgen_defer::message, Creature::mod_moves(), mon_flag_CONVERSATION, npc::name_and_activity(), npc_activities_menu(), NPC_CHAT_ACTIVITIES, NPC_CHAT_ACTIVITIES_BUTCHERY, NPC_CHAT_ACTIVITIES_CHOP_PLANKS, NPC_CHAT_ACTIVITIES_CHOP_TREES, NPC_CHAT_ACTIVITIES_CONSTRUCTION, NPC_CHAT_ACTIVITIES_CRAFT, NPC_CHAT_ACTIVITIES_DISASSEMBLY, NPC_CHAT_ACTIVITIES_FARMING, NPC_CHAT_ACTIVITIES_FISHING, NPC_CHAT_ACTIVITIES_MINING, NPC_CHAT_ACTIVITIES_MOPPING, NPC_CHAT_ACTIVITIES_MOVE_LOOT, NPC_CHAT_ACTIVITIES_READ_REPEATEDLY, NPC_CHAT_ACTIVITIES_UNASSIGN, NPC_CHAT_ACTIVITIES_VEHICLE_DECONSTRUCTION, NPC_CHAT_ACTIVITIES_VEHICLE_REPAIR, NPC_CHAT_ANIMAL_VEHICLE_FOLLOW, NPC_CHAT_ANIMAL_VEHICLE_STOP_FOLLOW, NPC_CHAT_AWAKE, NPC_CHAT_CLEAR_OVERRIDES, NPC_CHAT_COMMAND_MAGIC_VEHICLE_FOLLOW, NPC_CHAT_COMMAND_MAGIC_VEHICLE_STOP_FOLLOW, NPC_CHAT_DANGER, NPC_CHAT_DISMOUNT, NPC_CHAT_EMOTE, NPC_CHAT_FOLLOW, NPC_CHAT_GUARD, NPC_CHAT_MOUNT, NPC_CHAT_MOVE_TO_POS, NPC_CHAT_ORDERS, NPC_CHAT_SENTENCE, NPC_CHAT_START_SEMINAR, NPC_CHAT_TALK, NPC_CHAT_YELL, NPC_MISSION_GUARD_ALLY, npc_select_menu(), npc_temp_orders_menu(), npcs_select_menu(), popup(), Creature::pos(), Creature::posz(), talk_function::teach_domain::prof, proficiency_id, uilist::query(), uilist::ret, talk_function::revert_activity(), rl_dist(), Character::sees(), SEEX, Character::shout(), talk_function::teach_domain::skill, skill_id, talk_function::sort_loot(), talk_function::teach_domain::spell, spell_id, talk_function::start_training_gen(), talk_function::stop_guard(), string_format(), talk_function::teach_domain::style, avatar::talk_to(), tell_magic_veh_stop_following(), tell_magic_veh_to_follow(), tell_veh_stop_following(), uilist::text, music::title, training_select_menu(), trait_PROF_FOODP, monster::type, u, and talk_function::wake_up().

Referenced by do_regular_action().

◆ check_mod_data()

bool game::check_mod_data ( const std::vector< mod_id > &  opts,
loading_ui ui 
)

Check if mods can be successfully loaded.

Parameters
optscheck specific mods (or all if unspecified)
Returns
whether all mods were successfully loaded

Definition at line 489 of file game.cpp.

490 {
491  dependency_tree &tree = world_generator->get_mod_manager().get_tree();
492 
493  // deduplicated list of mods to check
494  std::set<mod_id> check( opts.begin(), opts.end() );
495 
496  // if no specific mods specified check all non-obsolete mods
497  if( check.empty() ) {
498  for( const mod_id &e : world_generator->get_mod_manager().all_mods() ) {
499  if( !e->obsolete ) {
500  check.emplace( e );
501  }
502  }
503  }
504 
505  if( check.empty() ) {
506  world_generator->set_active_world( nullptr );
507  world_generator->init();
508  const std::vector<mod_id> mods_empty;
509  WORLD *test_world = world_generator->make_new_world( mods_empty );
510  world_generator->set_active_world( test_world );
511 
512  // if no loadable mods then test core data only
513  try {
514  load_core_data( ui );
516  } catch( const std::exception &err ) {
517  std::cerr << "Error loading data from json: " << err.what() << std::endl;
518  }
519 
520  std::string world_name = world_generator->active_world->world_name;
521  world_generator->delete_world( world_name, true );
522 
523  MAPBUFFER.clear();
525  }
526 
527  for( const auto &e : check ) {
528  world_generator->set_active_world( nullptr );
529  world_generator->init();
530  const std::vector<mod_id> mods_empty;
531  WORLD *test_world = world_generator->make_new_world( mods_empty );
532  world_generator->set_active_world( test_world );
533 
534  if( !e.is_valid() ) {
535  std::cerr << "Unknown mod: " << e.str() << std::endl;
536  return false;
537  }
538 
539  const MOD_INFORMATION &mod = *e;
540 
541  if( !tree.is_available( mod.ident ) ) {
542  std::cerr << "Missing dependencies: " << mod.name() << "\n"
543  << tree.get_node( mod.ident )->s_errors() << std::endl;
544  return false;
545  }
546 
547  std::cout << "Checking mod " << mod.name() << " [" << mod.ident.str() << "]" << std::endl;
548 
549  try {
550  load_core_data( ui );
551 
552  // Load any dependencies and de-duplicate them
553  std::vector<mod_id> dep_vector = tree.get_dependencies_of_X_as_strings( mod.ident );
554  std::set<mod_id> dep_set( dep_vector.begin(), dep_vector.end() );
555  for( const auto &dep : dep_set ) {
556  load_data_from_dir( dep->path, dep->ident.str(), ui );
557  }
558 
559  // Load mod itself
560  load_data_from_dir( mod.path, mod.ident.str(), ui );
562  } catch( const std::exception &err ) {
563  std::cerr << "Error loading data: " << err.what() << std::endl;
564  }
565 
566  std::string world_name = world_generator->active_world->world_name;
567  world_generator->delete_world( world_name, true );
568 
569  MAPBUFFER.clear();
571  }
572  return true;
573 }
void finalize_loaded_data(loading_ui &ui)
Called to finalize the loaded data.
Definition: init.cpp:677
static DynamicDataLoader & get_instance()
Returns the single instance of this class.
Definition: init.cpp:119
std::string s_errors()
dependency_node * get_node(const mod_id &key)
bool is_available(const mod_id &key)
std::vector< mod_id > get_dependencies_of_X_as_strings(const mod_id &key)
void load_core_data(loading_ui &ui)
Loads core dynamic data.
Definition: game.cpp:580
void load_data_from_dir(const cata_path &path, const std::string &src, loading_ui &ui)
Loads dynamic data from the given directory.
Definition: game.cpp:589
void clear()
Delete all buffered submaps.
Definition: mapbuffer.cpp:53
mapbuffer MAPBUFFER
Definition: mapbuffer.cpp:48
static void check(const ma_requirements &req, const std::string &display_text)
Definition: overmap_ui.h:25
overmapbuffer overmap_buffer

References check(), mapbuffer::clear(), overmapbuffer::clear(), DynamicDataLoader::finalize_loaded_data(), dependency_tree::get_dependencies_of_X_as_strings(), DynamicDataLoader::get_instance(), dependency_tree::get_node(), dependency_tree::is_available(), load_core_data(), load_data_from_dir(), MAPBUFFER, overmap_buffer, dependency_node::s_errors(), and world_generator.

◆ check_near_zone()

bool game::check_near_zone ( const zone_type_id type,
const tripoint where 
) const

Checks whether or not there is a zone of particular type nearby.

Definition at line 6852 of file game.cpp.

6853 {
6854  return zone_manager::get_manager().has_near( type, m.getglobal( where ) );
6855 }
static zone_manager & get_manager()
Definition: clzones.h:550
bool has_near(const zone_type_id &type, const tripoint_abs_ms &where, int range=MAX_DISTANCE, const faction_id &fac=your_fac) const
Definition: clzones.cpp:1011

References zone_manager::get_manager(), map::getglobal(), zone_manager::has_near(), m, and type.

◆ check_safe_mode_allowed()

bool game::check_safe_mode_allowed ( bool  repeat_safe_mode_warnings = true)

Check whether movement is allowed according to safe mode settings.

Returns
true if the movement is allowed, otherwise false.

Definition at line 10223 of file game.cpp.

10224 {
10225  if( !repeat_safe_mode_warnings && safe_mode_warning_logged ) {
10226  // Already warned player since safe_mode_warning_logged is set.
10227  return false;
10228  }
10229 
10230  std::string msg_ignore = press_x( ACTION_IGNORE_ENEMY );
10231  if( !msg_ignore.empty() ) {
10232  std::wstring msg_ignore_wide = utf8_to_wstr( msg_ignore );
10233  // Operate on a wide-char basis to prevent corrupted multi-byte string
10234  msg_ignore_wide[0] = towlower( msg_ignore_wide[0] );
10235  msg_ignore = wstr_to_utf8( msg_ignore_wide );
10236  }
10237 
10238  if( u.has_effect( effect_laserlocked ) ) {
10239  // Automatic and mandatory safemode. Make BLOODY sure the player notices!
10240  if( u.get_int_base() < 5 || u.has_trait( trait_PROF_CHURL ) ) {
10242  _( "There's an angry red dot on your body, %s to brush it off." ), msg_ignore );
10243  } else {
10245  _( "You are being laser-targeted, %s to ignore." ), msg_ignore );
10246  }
10247  safe_mode_warning_logged = true;
10248  return false;
10249  }
10250  if( safe_mode != SAFE_MODE_STOP ) {
10251  return true;
10252  }
10253  // Currently driving around, ignore the monster, they have no chance against a proper car anyway (-:
10254  if( u.controlling_vehicle && !get_option<bool>( "SAFEMODEVEH" ) ) {
10255  return true;
10256  }
10257  // Monsters around and we don't want to run
10258  std::string spotted_creature_text;
10259  const monster_visible_info &mon_visible = u.get_mon_visible();
10260  const std::vector<shared_ptr_fast<monster>> &new_seen_mon = mon_visible.new_seen_mon;
10261 
10262  const nc_color mon_color = c_red;
10263  const nc_color dir_color = c_light_blue;
10264  if( new_seen_mon.empty() ) {
10265  // naming consistent with code in game::mon_info
10266  spotted_creature_text = colorize( _( "a survivor" ), mon_color );
10268  } else if( new_seen_mon.size() == 1 ) {
10269  const shared_ptr_fast<monster> &mon = new_seen_mon.back();
10270  const std::string dist_text = string_format( _( "%d tiles" ), rl_dist( u.pos(), mon->pos() ) );
10271  //~ %s: Cardinal/ordinal direction ("east")
10272  const std::string dir_text = string_format( _( "to the %s" ),
10273  colorize( direction_name( direction_from( u.pos(), mon->pos() ) ), dir_color ) );
10274  //~ %1$s: Name of monster spotted ("headless zombie")
10275  //~ %2$s: Distance to monster ("17 tiles")
10276  //~ %3$s: Description of where the monster is ("to the east")
10277  spotted_creature_text = string_format( pgettext( "monster description", "%1$s %2$s %3$s" ),
10278  colorize( mon->name(), mon_color ),
10279  dist_text,
10280  dir_text );
10281  get_safemode().lastmon_whitelist = mon->name();
10282  } else {
10283  // We've got multiple monsters to inform about.
10284  // Find the range of distances.
10285  int min_dist = INT_MAX;
10286  int max_dist = 0;
10287  // Find the most frequent type to call out by name.
10288  std::unordered_map<std::string, std::vector<const monster *>> mons_by_name;
10289  for( const shared_ptr_fast<monster> &mon : new_seen_mon ) {
10290  min_dist = std::min( min_dist, rl_dist( u.pos(), mon->pos() ) );
10291  max_dist = std::max( min_dist, rl_dist( u.pos(), mon->pos() ) );
10292  mons_by_name[mon->name()].push_back( mon.get() );
10293  }
10294  const std::vector<const monster *> &most_frequent_mon = std::max_element( mons_by_name.begin(),
10295  mons_by_name.end(), []( const auto & a, const auto & b ) {
10296  return a.second.size() < b.second.size();
10297  } )->second;
10298 
10299  const monster *const mon = most_frequent_mon.back();
10300  const std::string most_frequent_mon_text = colorize( most_frequent_mon.size() > 1 ?
10301  string_format( "%d %s",
10302  most_frequent_mon.size(), mon->name( most_frequent_mon.size() ) ) : mon->name(), mon_color );
10303 
10304  const std::string dist_text = min_dist == max_dist ?
10305  //~ %d: Distance to all monsters ("7")
10306  string_format( _( "%d tiles" ), max_dist ) :
10307  //~ %d, %d: Minimum and Maximum distance to the monsters ("5"; "20")
10308  string_format( _( "%d-%d tiles" ), min_dist, max_dist );
10309 
10310  // If they're all in one or two directions, let's call that out.
10311  // Otherwise, we can say they're in "various directions", so it's clear they aren't clustered.
10312  std::set<direction> most_frequent_mon_dirs;
10313  std::transform( most_frequent_mon.begin(), most_frequent_mon.end(),
10314  std::inserter( most_frequent_mon_dirs,
10315  most_frequent_mon_dirs.begin() ), [&]( const monster * const mon ) {
10316  return direction_from( u.pos(), mon->pos() );
10317  } );
10318  std::string dir_text;
10319  if( most_frequent_mon_dirs.size() == 1 ) {
10320  //~ %s: Cardinal/ordinal direction ("east")
10321  dir_text = string_format( _( "to the %s" ),
10322  colorize( direction_name( *most_frequent_mon_dirs.begin() ), dir_color ) );
10323  } else if( most_frequent_mon_dirs.size() == 2 ) {
10324  //~ %s, %s: Cardinal/ordinal directions ("east"; "southwest")
10325  dir_text = string_format( _( "to the %s and %s" ),
10326  colorize( direction_name( *most_frequent_mon_dirs.begin() ), dir_color ),
10327  colorize( direction_name( *std::next( most_frequent_mon_dirs.begin() ) ), dir_color ) );
10328  } else {
10329  dir_text = colorize( _( "in various directions" ), dir_color );
10330  }
10331 
10332  // Finally, let's mention that there are other monsters around that we didn't name explicitly.
10333  const size_t other_mon_count = new_seen_mon.size() - most_frequent_mon.size();
10334  std::string other_mon_text;
10335  if( other_mon_count > 0 ) {
10336  //~ %s: Description of other monster count ("4 others"), %d: How many other monsters there are
10337  other_mon_text = string_format( _( " and %s" ),
10338  colorize( string_format( n_gettext( _( "%d other" ), _( "%d others" ),
10339  other_mon_count ), other_mon_count ), mon_color ) );
10340  }
10341 
10342  //~ %1$s: Description of primary monster spotted ("3 fat zombies")
10343  //~ %2$s: Description of how far away the monsters are ("7 tiles" or "5-20 tiles")
10344  //~ %3$s: Description of where the primary monster is ("to the east and south")
10345  //~ %4$s: Description of any other monsters spotted (" and 4 others")
10346  spotted_creature_text = string_format( _( "%1$s %2$s %3$s%4$s" ), most_frequent_mon_text,
10347  dist_text,
10348  dir_text,
10349  other_mon_text );
10350  get_safemode().lastmon_whitelist = mon->name();
10351  }
10352 
10353  std::string whitelist;
10354  if( !get_safemode().empty() ) {
10355  whitelist = string_format( _( ", or %s to whitelist the monster" ),
10357  }
10358 
10359  const std::string msg_safe_mode = press_x( ACTION_TOGGLE_SAFEMODE );
10361  _( "Spotted %1$s -- safe mode is on! (%2$s to turn it off, %3$s to ignore monster%4$s)" ),
10362  spotted_creature_text, msg_safe_mode, msg_ignore, whitelist );
10363  safe_mode_warning_logged = true;
10364  return false;
10365 }
std::string press_x(action_id act)
Definition: action.cpp:528
@ ACTION_IGNORE_ENEMY
Ignore the enemy that triggered safemode.
Definition: action.h:237
@ ACTION_WHITELIST_ENEMY
Whitelist the enemy that triggered safemode.
Definition: action.h:239
@ ACTION_TOGGLE_SAFEMODE
Turn safemode on/off, while leaving autosafemode intact.
Definition: action.h:229
std::wstring utf8_to_wstr(const std::string &str)
std::string wstr_to_utf8(const std::wstring &wstr)
int get_int_base() const
Definition: character.cpp:4156
monster_visible_info & get_mon_visible()
Definition: avatar.h:326
bool safe_mode_warning_logged
Definition: game.h:1164
std::string name(unsigned int quantity=1) const
Definition: monster.cpp:722
std::string lastmon_whitelist
Definition: safemode_ui.h:100
std::string npc_type_name()
Definition: safemode_ui.cpp:39
std::string colorize(const std::string &text, const nc_color &color)
Definition: color.cpp:742
#define c_light_blue
Definition: color.h:27
direction direction_from(const coords::coord_point< Point, Origin, Scale, LhsInBounds > &loc1, const coords::coord_point< Point, Origin, Scale, RhsInBounds > &loc2)
Definition: coordinates.h:790
@ gmf_bypass_cooldown
Definition: enums.h:375
static const efftype_id effect_laserlocked("laserlocked")
static const trait_id trait_PROF_CHURL("PROF_CHURL")
@ SAFE_MODE_STOP
Definition: game.h:64
std::string direction_name(const direction dir)
Definition: line.cpp:612
static constexpr double a
Definition: magic.cpp:1566
static constexpr double b
Definition: magic.cpp:1567
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16
safemode & get_safemode()
Definition: safemode_ui.cpp:28
Structure allowing a combination of game_message_type and game_message_flags.
Definition: enums.h:380
std::vector< shared_ptr_fast< monster > > new_seen_mon
Definition: avatar.h:64
#define n_gettext(STRING1, STRING2, COUNT)
Definition: translations.h:91

References _, a, ACTION_IGNORE_ENEMY, ACTION_TOGGLE_SAFEMODE, ACTION_WHITELIST_ENEMY, add_msg(), b, c_light_blue, c_red, colorize(), Character::controlling_vehicle, direction_from(), direction_name(), effect_laserlocked, Character::get_int_base(), avatar::get_mon_visible(), get_safemode(), gmf_bypass_cooldown, Creature::has_effect(), Character::has_trait(), safemode::lastmon_whitelist, m_warning, max(), min(), n_gettext, monster::name(), monster_visible_info::new_seen_mon, safemode::npc_type_name(), pgettext, Creature::pos(), press_x(), rl_dist(), safe_mode, SAFE_MODE_STOP, safe_mode_warning_logged, string_format(), trait_PROF_CHURL, u, utf8_to_wstr(), and wstr_to_utf8().

Referenced by do_regular_action().

◆ check_zone()

bool game::check_zone ( const zone_type_id type,
const tripoint where 
) const

Definition at line 6847 of file game.cpp.

6848 {
6849  return zone_manager::get_manager().has( type, m.getglobal( where ) );
6850 }
bool has(const zone_type_id &type, const tripoint_abs_ms &where, const faction_id &fac=your_fac) const
Definition: clzones.cpp:1003

References zone_manager::get_manager(), map::getglobal(), zone_manager::has(), m, and type.

Referenced by place_player().

◆ cleanup_dead()

void game::cleanup_dead ( )

Definition at line 4813 of file game.cpp.

4814 {
4815  // Dead monsters need to stay in the tracker until everything else that needs to die does so
4816  // This is because dying monsters can still interact with other dying monsters (@ref Creature::killer)
4817  bool monster_is_dead = critter_tracker->kill_marked_for_death();
4818 
4819  bool npc_is_dead = false;
4820  // can't use all_npcs as that does not include dead ones
4821  for( const auto &n : critter_tracker->active_npc ) {
4822  if( n->is_dead() ) {
4823  n->die( nullptr ); // make sure this has been called to create corpses etc.
4824  npc_is_dead = true;
4825  }
4826  }
4827 
4828  if( monster_is_dead ) {
4829  // From here on, pointers to creatures get invalidated as dead creatures get removed.
4830  critter_tracker->remove_dead();
4831  }
4832 
4833  if( npc_is_dead ) {
4834  for( auto it = critter_tracker->active_npc.begin(); it != critter_tracker->active_npc.end(); ) {
4835  if( ( *it )->is_dead() ) {
4836  get_avatar().get_mon_visible().remove_npc( ( *it ).get() );
4837  remove_npc_follower( ( *it )->getID() );
4838  overmap_buffer.remove_npc( ( *it )->getID() );
4839  it = critter_tracker->active_npc.erase( it );
4840  } else {
4841  it++;
4842  }
4843  }
4844  }
4845 
4846  critter_died = false;
4847 }
void remove_npc_follower(const character_id &id)
Remove follower id from follower set.
Definition: game.cpp:1731
pimpl< creature_tracker > critter_tracker
Definition: game.h:1099
bool critter_died
Has anything died in this turn and needs to be cleaned up?
Definition: game.h:1184
shared_ptr_fast< npc > remove_npc(const character_id &id)
Find npc by id and if found, erase it from the npc list and return it ( or return nullptr if not foun...
void remove_npc(npc *n)
Definition: avatar.cpp:2077

References critter_died, critter_tracker, get_avatar, avatar::get_mon_visible(), overmap_buffer, overmapbuffer::remove_npc(), monster_visible_info::remove_npc(), and remove_npc_follower().

◆ clear_zombies()

void game::clear_zombies ( )

Redirects to the creature_tracker clear() function.

Definition at line 5290 of file game.cpp.

5291 {
5292  critter_tracker->clear();
5293 }

References critter_tracker.

Referenced by setup().

◆ climb_down()

void game::climb_down ( const tripoint examp)

Climb down from a ledge.

Player is prompted to deploy grappling hook, webs or detach vines if applicable. Otherwise the safest available affordance (see above) is detected and used. The player is shown a confirmation query with an assessment of falling risk and damage.

Definition at line 13536 of file game.cpp.

13537 {
13538  uilist cmenu;
13539  cmenu.text = _( "How would you prefer to climb down?" );
13540 
13541  climb_down_menu_gen( examp, cmenu );
13542 
13543  // If there would only be one choice, skip the menu.
13544  if( cmenu.entries.size() == 1 ) {
13545  climb_down_menu_pick( examp, cmenu.entries[0].retval );
13546  } else {
13547  cmenu.query();
13548  climb_down_menu_pick( examp, cmenu.ret );
13549  }
13550 }
void climb_down_menu_gen(const tripoint &examp, uilist &cmenu)
Definition: game.cpp:13452
bool climb_down_menu_pick(const tripoint &examp, int retval)
Definition: game.cpp:13524
std::vector< uilist_entry > entries
Definition: ui.h:422

References _, climb_down_menu_gen(), climb_down_menu_pick(), uilist::entries, uilist::query(), uilist::ret, and uilist::text.

Referenced by do_regular_action().

◆ climb_down_menu_gen()

void game::climb_down_menu_gen ( const tripoint examp,
uilist cmenu 
)

Definition at line 13452 of file game.cpp.

13453 {
13454  // NOTE this menu may be merged with the iexamine::ledge menu, manage keys carefully!
13455 
13456  map &here = get_map();
13458 
13459  if( !here.valid_move( you.pos(), examp, false, true ) ) {
13460  // Can't move horizontally to the ledge
13461  return;
13462  }
13463 
13464  // Scan the height of the drop and what's in the way.
13465  const climbing_aid::fall_scan fall( examp );
13466 
13467  add_msg_debug( debugmode::DF_IEXAMINE, "Ledge height %d", fall.height );
13468  if( fall.height == 0 ) {
13469  you.add_msg_if_player( _( "You can't climb down there." ) );
13470  return;
13471  }
13472 
13473  // This is used to mention object names. TODO make this more flexible.
13474  std::string target_disp_name = m.disp_name( fall.pos_furniture_or_floor() );
13475 
13477 
13478  climbing_aid::aid_list aids = climbing_aid::list( conditions );
13479 
13480  // Debug:
13481  {
13482  add_msg_debug( debugmode::DF_IEXAMINE, "Climbing aid conditions: %d", conditions.size() );
13483  for( climbing_aid::condition &cond : conditions ) {
13484  add_msg_debug( debugmode::DF_IEXAMINE, cond.category_string() + ": " + cond.flag );
13485  }
13486  add_msg_debug( debugmode::DF_IEXAMINE, "Climbing aids available: %d", aids.size() );
13487  for( const climbing_aid *aid : climbing_aid::list_all( conditions ) ) {
13488  add_msg_debug( debugmode::DF_IEXAMINE, "#%d %s: %s (%s)",
13489  climb_affordance_menu_encode( aid->id ), aid->id.str(),
13490  aid->down.menu_text.translated(), target_disp_name );
13491  }
13492  add_msg_debug( debugmode::DF_IEXAMINE, "%d-level drop; %d until furniture; %d until creature.",
13493  fall.height, fall.height_until_furniture, fall.height_until_creature );
13494  }
13495 
13496  for( const climbing_aid *aid : aids ) {
13497  // Enable climbing aid unless it would deploy furniture in occupied tiles.
13498  bool enable_aid = true;
13499  if( aid->down.deploys_furniture() &&
13500  fall.height_until_furniture < std::min( fall.height, aid->down.max_height ) ) {
13501  // Can't deploy because it would overwrite existing furniture.
13502  enable_aid = false;
13503  }
13504 
13505  // Certain climbing aids can't be used for partial descent.
13506  if( !aid->down.allow_remaining_height && aid->down.max_height < fall.height ) {
13507  // TODO this check could block the safest non-deploying aid!
13508  enable_aid = false;
13509  }
13510 
13511  int hotkey = aid->down.menu_hotkey;
13512  if( hotkey == 0 ) {
13513  // Deployables require a hotkey def and we only show one non-deployable; use 'c' for it.
13514  hotkey = 'c';
13515  }
13516 
13517  std::string text_translated = enable_aid ?
13518  aid->down.menu_text.translated() : aid->down.menu_cant.translated();
13519  cmenu.addentry( climb_affordance_menu_encode( aid->id ), enable_aid, hotkey,
13520  string_format( text_translated, target_disp_name ) );
13521  }
13522 }
Scans downwards from a tile to assess what lies between it and solid ground.
Definition: climbing.h:89
A "Climbing Aid" as defined here is any one trait, mutation, tool, furniture terrain,...
Definition: climbing.h:26
static condition_list detect_conditions(Character &you, const tripoint &examp)
Definition: climbing.cpp:329
std::vector< const climbing_aid * > aid_list
Definition: climbing.h:68
static aid_list list(const condition_list &cond)
Definition: climbing.cpp:254
static aid_list list_all(const condition_list &cond)
Definition: climbing.cpp:271
std::vector< condition > condition_list
Definition: climbing.h:66
bool valid_move(const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
Returns true if a creature could walk from from to to in one step.
Definition: map.cpp:2542
std::string disp_name(const tripoint &p)
Definition: map.cpp:1694
static int climb_affordance_menu_encode(const climbing_aid_id &aid_id)
Definition: game.cpp:13438
#define add_msg_debug(type,...)
Definition: messages.h:177
@ DF_IEXAMINE
Definition: debug.h:259

References _, add_msg_debug, Character::add_msg_if_player(), uilist::addentry(), climb_affordance_menu_encode(), climbing_aid::detect_conditions(), debugmode::DF_IEXAMINE, map::disp_name(), get_map, get_player_character, climbing_aid::fall_scan::height, climbing_aid::fall_scan::height_until_creature, climbing_aid::fall_scan::height_until_furniture, climbing_aid::list(), climbing_aid::list_all(), m, min(), Creature::pos(), climbing_aid::fall_scan::pos_furniture_or_floor(), string_format(), and map::valid_move().

Referenced by climb_down().

◆ climb_down_menu_pick()

bool game::climb_down_menu_pick ( const tripoint examp,
int  retval 
)

Definition at line 13524 of file game.cpp.

13525 {
13527 
13528  if( climb_affordance_menu_decode( retval, aid_id ) ) {
13529  climb_down_using( examp, aid_id );
13530  return true;
13531  } else {
13532  return false;
13533  }
13534 }
void climb_down_using(const tripoint &examp, climbing_aid_id aid, bool deploy_affordance=false)
Definition: game.cpp:13552
static const climbing_aid_id climbing_aid_default("default")
static bool climb_affordance_menu_decode(int retval, climbing_aid_id &aid_id)
Definition: game.cpp:13442

References climb_affordance_menu_decode(), climb_down_using(), and climbing_aid_default.

Referenced by climb_down().

◆ climb_down_using()

void game::climb_down_using ( const tripoint examp,
climbing_aid_id  aid,
bool  deploy_affordance = false 
)

Definition at line 13552 of file game.cpp.

13553 {
13554  const climbing_aid &aid = aid_id.obj();
13555 
13556  map &here = get_map();
13558 
13559  // If player is grabbed, trapped, or somehow otherwise movement-impeded, first try to break free
13560  if( !you.move_effects( false ) ) {
13561  // move_effects determined we could not move, waste all moves
13562  you.set_moves( 0 );
13563  return;
13564  }
13565 
13566  if( !here.valid_move( you.pos(), examp, false, true ) ) {
13567  // Can't move horizontally to the ledge
13568  return;
13569  }
13570 
13571  // Scan the height of the drop and what's in the way.
13572  const climbing_aid::fall_scan fall( examp );
13573 
13574  int estimated_climb_cost = you.climbing_cost( fall.pos_bottom(), examp );
13575  const float fall_mod = you.fall_damage_mod();
13576  add_msg_debug( debugmode::DF_IEXAMINE, "Climb cost %d", estimated_climb_cost );
13577  add_msg_debug( debugmode::DF_IEXAMINE, "Fall damage modifier %.2f", fall_mod );
13578 
13579  std::string query;
13580 
13581  // The most common query reads as follows:
13582  // It [seems somewhat risky] to climb down like this.
13583  // Falling [would hurt].
13584  // You [probably won't be able to climb back up].
13585  // Climb down the rope?
13586 
13587  // Calculate chance of slipping. Prints possible causes to log.
13588  int slip_chance = slip_down_chance( climb_maneuver::down, aid_id, true );
13589 
13590  // Roughly estimate damage if we should fall.
13591  int damage_estimate = 10 * fall.height;
13592  if( damage_estimate <= 30 ) {
13593  damage_estimate *= fall_mod;
13594  } else {
13595  damage_estimate *= std::pow( fall_mod, 30.f / damage_estimate );
13596  }
13597 
13598  // Rough messaging about safety. "seems safe" can leave a 1-2% chance unlike "perfectly safe".
13599  bool seems_perfectly_safe = slip_chance < -5 && aid.down.max_height >= fall.height;
13600  if( seems_perfectly_safe ) {
13601  query = _( "It <color_green>seems perfectly safe</color> to climb down like this." );
13602  } else if( slip_chance < 3 ) {
13603  query = _( "It <color_green>seems safe</color> to climb down like this." );
13604  } else if( slip_chance < 8 ) {
13605  query = _( "It <color_yellow>seems a bit tricky</color> to climb down like this." );
13606  } else if( slip_chance < 20 ) {
13607  query = _( "It <color_yellow>seems somewhat risky</color> to climb down like this." );
13608  } else if( slip_chance < 50 ) {
13609  query = _( "It <color_red>seems very risky</color> to climb down like this." );
13610  } else if( slip_chance < 80 ) {
13611  query = _( "It <color_pink>looks like you'll slip</color> if you climb down like this." );
13612  } else {
13613  query = _( "It <color_pink>doesn't seem possible to climb down safely</color>." );
13614  }
13615 
13616  if( !seems_perfectly_safe ) {
13617  std::string hint_fall_damage;
13618  if( damage_estimate >= 100 ) {
13619  hint_fall_damage = _( "Falling <color_pink>would kill you</color>." );
13620  } else if( damage_estimate >= 60 ) {
13621  hint_fall_damage = _( "Falling <color_pink>could cripple or kill you</color>." );
13622  } else if( damage_estimate >= 30 ) {
13623  hint_fall_damage = _( "Falling <color_pink>would break bones.</color>." );
13624  } else if( damage_estimate >= 15 ) {
13625  hint_fall_damage = _( "Falling <color_red>would hurt badly</color>." );
13626  } else if( damage_estimate >= 5 ) {
13627  hint_fall_damage = _( "Falling <color_red>would hurt</color>." );
13628  } else {
13629  hint_fall_damage = _( "Falling <color_green>wouldn't hurt much</color>." );
13630  }
13631  query += "\n";
13632  query += hint_fall_damage;
13633  }
13634 
13635  if( fall.height > aid.down.max_height ) {
13636  // Warn the player that they will fall even after a successful climb
13637  int remaining_height = fall.height - aid.down.max_height;
13638  query += "\n";
13639  query += string_format( n_gettext(
13640  "Even if you climb down safely, you will fall <color_yellow>at least %d story</color>.",
13641  "Even if you climb down safely, you will fall <color_red>at least %d stories</color>.",
13642  remaining_height ), remaining_height );
13643  }
13644 
13645  // Certain climbing aids make it easy to climb back up, usually by making furniture.
13646  if( aid.down.easy_climb_back_up >= fall.height ) {
13647  estimated_climb_cost = 50;
13648  }
13649 
13650  // Note, this easy_climb_back_up can be set by factors other than the climbing aid.
13651  bool easy_climb_back_up = false;
13652  std::string hint_climb_back;
13653  if( estimated_climb_cost <= 0 ) {
13654  hint_climb_back = _( "You <color_red>probably won't be able to climb back up</color>." );
13655  } else if( estimated_climb_cost < 200 ) {
13656  hint_climb_back = _( "You <color_green>should be easily able to climb back up</color>." );
13657  easy_climb_back_up = true;
13658  } else {
13659  hint_climb_back = _( "You <color_yellow>may have problems trying to climb back up</color>." );
13660  }
13661  query += "\n";
13662  query += hint_climb_back;
13663 
13664  std::string query_prompt = _( "Climb down?" );
13665  if( !aid.down.confirm_text.empty() ) {
13666  query_prompt = aid.down.confirm_text.translated();
13667  }
13668  query += "\n\n";
13669  query += query_prompt;
13670 
13671  add_msg_debug( debugmode::DF_GAME, "Generated climb_down prompt for the player." );
13672  add_msg_debug( debugmode::DF_GAME, "Climbing aid: %s / deploy furniture %d", std::string( aid_id ),
13673  int( deploy_affordance ) );
13674  add_msg_debug( debugmode::DF_GAME, "Slip chance %d / est damage %d", slip_chance, damage_estimate );
13675  add_msg_debug( debugmode::DF_GAME, "We can descend %d / total height %d", aid.down.max_height,
13676  fall.height );
13677 
13678  if( !seems_perfectly_safe || !easy_climb_back_up ) {
13679 
13680  // This is used to mention object names. TODO make this more flexible.
13681  std::string target_disp_name = m.disp_name( fall.pos_furniture_or_floor() );
13682 
13683  // Show the risk prompt.
13684  if( !query_yn( query.c_str(), target_disp_name ) ) {
13685  return;
13686  }
13687  }
13688 
13690  float weary_mult = 1.0f / you.exertion_adjusted_move_multiplier( ACTIVE_EXERCISE );
13691 
13692  you.mod_moves( -to_moves<int>( 1_seconds + 1_seconds * fall_mod ) * weary_mult );
13693  you.setpos( examp );
13694 
13695  // Pre-descent message.
13696  if( !aid.down.msg_before.empty() ) {
13698  }
13699 
13700  // Descent: perform one slip check per level
13701  tripoint descent_pos = examp;
13702  for( int i = 0; i < fall.height && i < aid.down.max_height; ++i ) {
13703  if( g->slip_down( climb_maneuver::down, aid_id, false ) ) {
13704  // The player has slipped and probably fallen.
13705  return;
13706  } else {
13707  descent_pos.z--;
13708  if( aid.down.deploys_furniture() ) {
13709  here.furn_set( descent_pos, aid.down.deploy_furn );
13710  }
13711  }
13712  }
13713 
13714  int descended_levels = examp.z - descent_pos.z;
13715  add_msg_debug( debugmode::DF_IEXAMINE, "Safe movement down %d Z-levels", descended_levels );
13716 
13717  // Post-descent logic...
13718 
13719  // Use up items after successful climb
13721  for( item &used_item : you.use_amount( itype_id( aid.base_condition.flag ),
13722  aid.base_condition.uses_item ) ) {
13723  used_item.spill_contents( you );
13724  }
13725  }
13726 
13727  // Pre-descent message.
13728  if( !aid.down.msg_after.empty() ) {
13730  }
13731 
13732  // You ride the ride, you pay the tithe.
13733  if( aid.down.cost.damage > 0 ) {
13734  you.apply_damage( nullptr, bodypart_id( "torso" ), aid.down.cost.damage );
13735  }
13736  if( aid.down.cost.pain > 0 ) {
13737  you.mod_pain( aid.down.cost.pain );
13738  }
13739  if( aid.down.cost.kcal > 0 ) {
13740  you.mod_stored_kcal( -aid.down.cost.kcal );
13741  }
13742  if( aid.down.cost.thirst > 0 ) {
13743  you.mod_thirst( aid.down.cost.thirst );
13744  }
13745 
13746  // vertical_move with force=true triggers traps (ie, fall) at the end of the move.
13747  g->vertical_move( -descended_levels, true );
13748 
13749  if( here.has_flag( ter_furn_flag::TFLAG_DEEP_WATER, you.pos() ) ) {
13750  you.set_underwater( true );
13751  g->water_affect_items( you );
13752  you.add_msg_if_player( _( "You climb down and dive underwater." ) );
13753  }
13754 }
int_id< body_part_type > bodypart_id
Definition: bodypart.h:32
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
void mod_stored_kcal(int nkcal, bool ignore_weariness=false)
Modifiers for need values exclusive to characters.
Definition: character.cpp:4426
std::list< item > use_amount(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >, bool select_ind=false)
Definition: character.cpp:9595
bool move_effects(bool attacking) override
Processes effects which may prevent the Character from moving (bear traps, crushed,...
void apply_damage(Creature *source, bodypart_id hurt, int dam, bool bypass_med=false) override
Actually hurt the player, hurts a body_part directly, no armor reduction.
Definition: character.cpp:8207
int climbing_cost(const tripoint &from, const tripoint &to) const
Checks both the neighborhoods of from and to for climbable surfaces, returns move cost of climbing fr...
void mod_thirst(int nthirst)
Definition: character.cpp:4528
float exertion_adjusted_move_multiplier(float level=-1.0f) const
Definition: character.cpp:4951
float fall_damage_mod() const override
Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels)
void set_underwater(bool)
void set_activity_level(float new_level)
Definition: character.cpp:6547
void setpos(const tripoint &p)
Definition: creature.cpp:188
void set_moves(int nmoves)
Definition: creature.cpp:2012
struct climbing_aid::down_t down
condition base_condition
Definition: climbing.h:149
int slip_down_chance(climb_maneuver maneuver, climbing_aid_id aid=climbing_aid_id::NULL_ID(), bool show_chance_messages=true)
Calculates the chance that slip_down will return true.
Definition: game.cpp:13281
bool furn_set(const tripoint &p, const furn_id &new_furniture, bool furn_reset=false, bool avoid_creatures=false)
furn_reset should be true if new_furniture is being set to f_null when the player is grab-moving furn...
Definition: map.cpp:1743
const T & obj() const
Returns the actual object this id refers to.
Definition: achievement.cpp:71
std::string translated(int num=1) const
Returns raw string if no translation is needed, otherwise returns the translated string.
bool empty() const
Whether the underlying string is empty, not matter what the context is or whether translation is need...
constexpr float ACTIVE_EXERCISE
@ DF_GAME
Definition: debug.h:258
std::string flag
Definition: climbing.h:40
translation msg_after
Definition: climbing.h:177
furn_str_id deploy_furn
Definition: climbing.h:181
climb_cost cost
Definition: climbing.h:180
translation msg_before
Definition: climbing.h:176
bool deploys_furniture() const noexcept
Definition: climbing.h:187
translation confirm_text
Definition: climbing.h:174
int z
Definition: point.h:134

References _, ACTIVE_EXERCISE, add_msg_debug, Character::add_msg_if_player(), Character::apply_damage(), climbing_aid::base_condition, climbing_aid::condition::cat, Character::climbing_cost(), climbing_aid::down_t::confirm_text, climbing_aid::down_t::cost, climbing_aid::climb_cost::damage, climbing_aid::down_t::deploy_furn, climbing_aid::down_t::deploys_furniture(), debugmode::DF_GAME, debugmode::DF_IEXAMINE, map::disp_name(), climbing_aid::down, down, climbing_aid::down_t::easy_climb_back_up, translation::empty(), Character::exertion_adjusted_move_multiplier(), Character::fall_damage_mod(), climbing_aid::condition::flag, map::furn_set(), g, get_map, get_player_character, map::has_flag(), climbing_aid::fall_scan::height, climbing_aid::item, climbing_aid::climb_cost::kcal, m, climbing_aid::down_t::max_height, Creature::mod_moves(), Character::mod_pain(), Character::mod_stored_kcal(), Character::mod_thirst(), Character::move_effects(), climbing_aid::down_t::msg_after, climbing_aid::down_t::msg_before, n_gettext, string_id< T >::obj(), climbing_aid::climb_cost::pain, Creature::pos(), climbing_aid::fall_scan::pos_bottom(), climbing_aid::fall_scan::pos_furniture_or_floor(), query_yn(), Character::set_activity_level(), Creature::set_moves(), Character::set_underwater(), Creature::setpos(), slip_down_chance(), string_format(), TFLAG_DEEP_WATER, climbing_aid::climb_cost::thirst, translation::translated(), Character::use_amount(), climbing_aid::condition::uses_item, map::valid_move(), and tripoint::z.

Referenced by climb_down_menu_pick().

◆ control_vehicle()

void game::control_vehicle ( )
private

Definition at line 5842 of file game.cpp.

5843 {
5844  if( vehicle *remote_veh = remoteveh() ) { // remote controls have priority
5845  for( const vpart_reference &vpr : remote_veh->get_avail_parts( "REMOTE_CONTROLS" ) ) {
5846  remote_veh->interact_with( vpr.pos() );
5847  return;
5848  }
5849  }
5850  vehicle *veh = nullptr;
5851  if( const optional_vpart_position vp = m.veh_at( u.pos() ) ) {
5852  veh = &vp->vehicle();
5853  const int controls_idx = veh->avail_part_with_feature( vp->mount(), "CONTROLS" );
5854  const int reins_idx = veh->avail_part_with_feature( vp->mount(), "CONTROL_ANIMAL" );
5855  const bool controls_ok = controls_idx >= 0; // controls available to "drive"
5856  const bool reins_ok = reins_idx >= 0 // reins + animal available to "drive"
5857  && veh->has_engine_type( fuel_type_animal, false )
5858  && veh->get_harnessed_animal();
5859  if( veh->player_in_control( u ) ) {
5860  // player already "driving" - offer ways to leave
5861  if( controls_ok ) {
5862  veh->interact_with( u.pos() );
5863  } else if( reins_idx >= 0 ) {
5864  u.controlling_vehicle = false;
5865  add_msg( m_info, _( "You let go of the reins." ) );
5866  }
5867  } else if( u.in_vehicle && ( controls_ok || reins_ok ) ) {
5868  // player not driving but has controls or reins on tile
5869  if( veh->is_locked ) {
5870  veh->interact_with( u.pos() );
5871  return; // interact_with offers to hotwire
5872  }
5873  if( !veh->handle_potential_theft( u ) ) {
5874  return; // player not owner and refused to steal
5875  }
5876  if( veh->engine_on ) {
5877  u.controlling_vehicle = true;
5878  add_msg( _( "You take control of the %s." ), veh->name );
5879  } else {
5880  veh->start_engines( true );
5881  }
5882  }
5883  }
5884  if( !veh ) { // no controls or animal reins under player position, search nearby
5885  int num_valid_controls = 0;
5886  std::optional<tripoint> vehicle_position;
5887  std::optional<vpart_reference> vehicle_controls;
5888  for( const tripoint &elem : m.points_in_radius( get_player_character().pos(), 1 ) ) {
5889  if( const optional_vpart_position vp = m.veh_at( elem ) ) {
5890  const std::optional<vpart_reference> controls = vp.value().part_with_feature( "CONTROLS", true );
5891  if( controls ) {
5892  num_valid_controls++;
5893  vehicle_position = elem;
5894  vehicle_controls = controls;
5895  }
5896  }
5897  }
5898  if( num_valid_controls < 1 ) {
5899  add_msg( _( "No vehicle controls found." ) );
5900  return;
5901  } else if( num_valid_controls > 1 ) {
5902  vehicle_position = choose_adjacent( _( "Control vehicle where?" ) );
5903  if( !vehicle_position ) {
5904  return;
5905  }
5906  const optional_vpart_position vp = m.veh_at( *vehicle_position );
5907  if( vp ) {
5908  vehicle_controls = vp.value().part_with_feature( "CONTROLS", true );
5909  if( !vehicle_controls ) {
5910  add_msg( _( "The vehicle doesn't have controls there." ) );
5911  return;
5912  }
5913  } else {
5914  add_msg( _( "No vehicle there." ) );
5915  return;
5916  }
5917  }
5918  // If we hit neither of those, there's only one set of vehicle controls, which should already have been found.
5919  if( vehicle_controls ) {
5920  veh = &vehicle_controls->vehicle();
5921  if( !veh->handle_potential_theft( u ) ) {
5922  return;
5923  }
5924  veh->interact_with( *vehicle_position );
5925  }
5926  }
5927  if( veh ) {
5928  // If we reached here, we gained control of a vehicle.
5929  // Clear the map memory for the area covered by the vehicle to eliminate ghost vehicles.
5930  for( const tripoint &target : veh->get_points() ) {
5931  u.memorize_clear_decoration( m.getglobal( target ), "vp_" );
5932  m.memory_cache_dec_set_dirty( target, true );
5933  }
5934  veh->is_following = false;
5935  veh->is_patrolling = false;
5936  veh->autopilot_on = false;
5937  veh->is_autodriving = false;
5938  }
5939 }
std::optional< tripoint > choose_adjacent(const std::string &message, const bool allow_vertical)
Request player input of adjacent tile, possibly including vertical tiles.
Definition: action.cpp:1188
bool in_vehicle
Definition: character.h:2693
void memorize_clear_decoration(const tripoint_abs_ms &p, std::string_view prefix="")
Definition: avatar.cpp:306
vehicle * remoteveh()
Returns the current remotely controlled vehicle.
Definition: game.cpp:2611
void memory_cache_dec_set_dirty(const tripoint &p, bool value) const
Definition: map.cpp:336
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:10109
Simple wrapper to forward functions that may return a std::optional to vpart_position.
std::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2698
bool engine_on
Definition: vehicle.h:2352
vehicle(const vproto_id &proto_id)
Definition: vehicle.cpp:214
int avail_part_with_feature(const point &pt, const std::string &f) const
Returns index of part at mount point pt which has given f flag and is_available(),...
Definition: vehicle.cpp:2805
std::string name
Definition: vehicle.h:2201
bool is_locked
Definition: vehicle.h:2356
void start_engines(bool take_control=false, bool autodrive=false)
bool is_patrolling
Definition: vehicle.h:2349
bool autopilot_on
Definition: vehicle.h:2360
bool handle_potential_theft(Character const &you, bool check_only=false, bool prompt=true)
Definition: vehicle.cpp:4686
void interact_with(const tripoint &p, bool with_pickup=false)
bool is_autodriving
Definition: vehicle.h:2347
const std::set< tripoint > & get_points(bool force_refresh=false, bool no_fake=false) const
Definition: vehicle.cpp:7725
monster * get_harnessed_animal() const
static const itype_id fuel_type_animal("animal")

References _, add_msg(), vehicle::autopilot_on, vehicle::avail_part_with_feature(), choose_adjacent(), Character::controlling_vehicle, vehicle::engine_on, fuel_type_animal, vehicle::get_harnessed_animal(), get_player_character, vehicle::get_points(), map::getglobal(), vehicle::handle_potential_theft(), vehicle::has_engine_type(), Character::in_vehicle, vehicle::interact_with(), vehicle::is_autodriving, vehicle::is_following, vehicle::is_locked, vehicle::is_patrolling, m, m_info, avatar::memorize_clear_decoration(), map::memory_cache_dec_set_dirty(), vehicle::name, optional_vpart_position::part_with_feature(), vehicle::player_in_control(), map::points_in_radius(), Creature::pos(), math_opers::pos(), remoteveh(), vehicle::start_engines(), u, map::veh_at(), and vehicle::vehicle().

Referenced by do_regular_action().

◆ create_or_get_main_ui_adaptor()

shared_ptr_fast< ui_adaptor > game::create_or_get_main_ui_adaptor ( )

In tiles mode w_terrain can have a different font (with a different tile dimension) or can be drawn by cata_tiles which uses tiles that again might have a different dimension then the normal font used everywhere else.

TERRAIN_WINDOW_WIDTH/TERRAIN_WINDOW_HEIGHT defines how many squares can be displayed in w_terrain (using it's specific tile dimension), not including partially drawn squares at the right/bottom. You should use it whenever you want to draw specific squares in that window or to determine whether a specific square is draw on screen (or outside the screen and needs scrolling).

TERRAIN_WINDOW_TERM_WIDTH/TERRAIN_WINDOW_TERM_HEIGHT defines the size of w_terrain in the standard font dimension (the font that everything else uses). You usually don't have to use it, expect for positioning of windows, because the window positions use the standard font dimension.

The code here calculates size available for w_terrain, caps it at max_view_size (the maximal view range than any character can have at any time). It is stored in TERRAIN_WINDOW_*.

Definition at line 3735 of file game.cpp.

3736 {
3738  if( !ui ) {
3739  main_ui_adaptor = ui = make_shared_fast<ui_adaptor>();
3740  ui->on_redraw( []( ui_adaptor & ui ) {
3741  g->draw( ui );
3742  } );
3743  ui->on_screen_resize( [this]( ui_adaptor & ui ) {
3744  // remove some space for the sidebar, this is the maximal space
3745  // (using standard font) that the terrain window can have
3746  const int sidebar_left = panel_manager::get_manager().get_width_left();
3747  const int sidebar_right = panel_manager::get_manager().get_width_right();
3748 
3750  TERRAIN_WINDOW_WIDTH = TERMX - ( sidebar_left + sidebar_right );
3753 
3754  /**
3755  * In tiles mode w_terrain can have a different font (with a different
3756  * tile dimension) or can be drawn by cata_tiles which uses tiles that again
3757  * might have a different dimension then the normal font used everywhere else.
3758  *
3759  * TERRAIN_WINDOW_WIDTH/TERRAIN_WINDOW_HEIGHT defines how many squares can
3760  * be displayed in w_terrain (using it's specific tile dimension), not
3761  * including partially drawn squares at the right/bottom. You should
3762  * use it whenever you want to draw specific squares in that window or to
3763  * determine whether a specific square is draw on screen (or outside the screen
3764  * and needs scrolling).
3765  *
3766  * TERRAIN_WINDOW_TERM_WIDTH/TERRAIN_WINDOW_TERM_HEIGHT defines the size of
3767  * w_terrain in the standard font dimension (the font that everything else uses).
3768  * You usually don't have to use it, expect for positioning of windows,
3769  * because the window positions use the standard font dimension.
3770  *
3771  * The code here calculates size available for w_terrain, caps it at
3772  * max_view_size (the maximal view range than any character can have at
3773  * any time).
3774  * It is stored in TERRAIN_WINDOW_*.
3775  */
3777 
3778  // Position of the player in the terrain window, it is always in the center
3779  POSX = TERRAIN_WINDOW_WIDTH / 2;
3781 
3783  point( sidebar_left, 0 ) );
3784 
3785  // minimap is always MINIMAP_WIDTH x MINIMAP_HEIGHT in size
3787 
3788  // need to init in order to avoid crash. gets updated by the panel code.
3790 
3791  ui.position_from_window( catacurses::stdscr );
3792  } );
3793  ui->mark_resize();
3794  }
3795  return ui;
3796 }
catacurses::window w_pixel_minimap
Definition: game.h:1112
catacurses::window w_minimap_ptr
Definition: game.h:1157
weak_ptr_fast< ui_adaptor > main_ui_adaptor
Definition: game.h:1212
catacurses::window w_minimap
Definition: game.h:1111
catacurses::window w_terrain_ptr
Definition: game.h:1156
int get_width_right() const
Definition: panels.cpp:390
int get_width_left() const
Definition: panels.cpp:398
static panel_manager & get_manager()
Definition: panels.h:132
Adaptor between UI code and the UI management system.
Definition: ui_manager.h:75
constexpr int MINIMAP_WIDTH
constexpr int MINIMAP_HEIGHT
void to_map_font_dimension(int &, int &)
Definition: game_ui.cpp:17
window stdscr
int TERRAIN_WINDOW_TERM_WIDTH
Definition: output.cpp:55
int TERRAIN_WINDOW_TERM_HEIGHT
Definition: output.cpp:56
int POSX
Definition: output.cpp:51
int TERRAIN_WINDOW_WIDTH
Definition: output.cpp:53
int POSY
Definition: output.cpp:52
int TERRAIN_WINDOW_HEIGHT
Definition: output.cpp:54

References g, panel_manager::get_manager(), panel_manager::get_width_left(), panel_manager::get_width_right(), main_ui_adaptor, MINIMAP_HEIGHT, MINIMAP_WIDTH, catacurses::newwin(), point, point_zero, POSX, POSY, catacurses::stdscr, TERMX, TERMY, TERRAIN_WINDOW_HEIGHT, TERRAIN_WINDOW_TERM_HEIGHT, TERRAIN_WINDOW_TERM_WIDTH, TERRAIN_WINDOW_WIDTH, to_map_font_dimension(), w_minimap, w_minimap_ptr, w_pixel_minimap, w_terrain, and w_terrain_ptr.

◆ create_starting_npcs()

void game::create_starting_npcs ( )
private

Definition at line 1277 of file game.cpp.

1278 {
1279  //We don't want more than one starting npc per starting location
1280  const int radius = 1;
1281  if( !overmap_buffer.get_npcs_near_player( radius ).empty() ) {
1282  return; //There is already an NPC in this starting location
1283  }
1284 
1285  shared_ptr_fast<npc> tmp = make_shared_fast<npc>();
1286  tmp->normalize();
1287  tmp->randomize( one_in( 2 ) ? NC_DOCTOR : NC_NONE );
1288  // hardcoded, consistent NPC position
1289  // start_loc::place_player relies on this and must be updated if this is changed
1290  tmp->spawn_at_precise( u.get_location() + point_north_west );
1291  overmap_buffer.insert_npc( tmp );
1292  tmp->form_opinion( u );
1293  tmp->set_attitude( NPCATT_NULL );
1294  //This sets the NPC mission. This NPC remains in the starting location.
1295  tmp->mission = NPC_MISSION_SHELTER;
1296  tmp->chatbin.first_topic = "TALK_SHELTER";
1297  tmp->toggle_trait( trait_NPC_STARTING_NPC );
1298  tmp->set_fac( faction_no_faction );
1299  //One random starting NPC mission
1300  tmp->add_new_mission( mission::reserve_random( ORIGIN_OPENER_NPC, tmp->global_omt_location(),
1301  tmp->getID() ) );
1302 }
tripoint_abs_ms get_location() const
Returns the location of the creature in map square coordinates (the most detailed coordinate system),...
Definition: creature.cpp:3232
static mission * reserve_random(mission_origin origin, const tripoint_abs_omt &p, const character_id &npc_id)
Definition: mission.cpp:291
std::vector< shared_ptr_fast< npc > > get_npcs_near_player(int radius)
Same as get_npcs_near(int,int,int,int) but uses player position as center.
void insert_npc(const shared_ptr_fast< npc > &who)
Adds the npc to an overmap ( based on the npcs current location ) and stores it there.
static const faction_id faction_no_faction("no_faction")
static const trait_id trait_NPC_STARTING_NPC("NPC_STARTING_NPC")
@ ORIGIN_OPENER_NPC
Definition: mission.h:48
@ NPCATT_NULL
Definition: npc.h:107
@ NPC_MISSION_SHELTER
Definition: npc.h:174
const npc_class_id NC_DOCTOR("NC_DOCTOR")
const npc_class_id NC_NONE("NC_NONE")
constexpr point point_north_west
Definition: point.h:260
bool one_in(int chance)
Definition: rng.cpp:108

References faction_no_faction, Creature::get_location(), overmapbuffer::get_npcs_near_player(), overmapbuffer::insert_npc(), NC_DOCTOR, NC_NONE, NPC_MISSION_SHELTER, NPCATT_NULL, one_in(), ORIGIN_OPENER_NPC, overmap_buffer, point_north_west, mission::reserve_random(), trait_NPC_STARTING_NPC, and u.

Referenced by start_game().

◆ critter_by_id()

template<typename T >
template Creature * game::critter_by_id< Creature > ( const character_id id)
Returns
The living creature with the given id. Returns null if no living creature with such an id exists. Never returns a dead creature. Currently only the player character and npcs have ids.

Definition at line 5155 of file game.cpp.

5156 {
5157  if( id == u.getID() ) {
5158  // player is always alive, therefore no is-dead check
5159  return dynamic_cast<T *>( &u );
5160  }
5161  return find_npc( id );
5162 }
npc * find_npc(character_id id)
Find the npc with the given ID.
Definition: game.cpp:1715

References find_npc(), Character::getID(), and u.

◆ death_screen()

void game::death_screen ( )
private

Definition at line 2982 of file game.cpp.

2983 {
2984  gamemode->game_over();
2989  follower_ids.clear();
2991 }
diary * get_avatar_diary()
Definition: avatar.cpp:424
void death_entry()
Definition: diary.cpp:610
std::unique_ptr< special_game > gamemode
Definition: game.h:1190
stats_tracker & stats()
Definition: game.cpp:3427
void disp_NPC_epilogues()
Definition: game.cpp:3612
const kill_tracker & get_kill_tracker() const
Definition: game.cpp:1272
void display_faction_epilogues()
Definition: game.cpp:3629
void display_messages()
Definition: messages.cpp:914
void show_scores_ui(const achievements_tracker &achievements, stats_tracker &stats, const kill_tracker &kills)
Definition: scores_ui.cpp:90

References achievements_tracker_ptr, diary::death_entry(), disp_NPC_epilogues(), display_faction_epilogues(), Messages::display_messages(), follower_ids, gamemode, avatar::get_avatar_diary(), get_kill_tracker(), show_scores_ui(), stats(), and u.

◆ despawn_monster()

void game::despawn_monster ( monster critter)

Despawn a specific monster, it's stored on the overmap.

Also removes it from the creature tracker. Keep in mind that any monster index may point to a different monster after calling this (or to no monster at all).

Definition at line 12750 of file game.cpp.

12751 {
12752  critter.on_unload();
12753  // hallucinations aren't stored, they come and go as they like
12754  if( !critter.is_hallucination() ) {
12755  // despawn_monster saves a copy of the monster in the overmap, so
12756  // this must be called after on_unload (which updates state)
12757  overmap_buffer.despawn_monster( critter );
12758  }
12759  remove_zombie( critter );
12760  // simulate it being dead so further processing of it (e.g. in monmove) will yield
12761  critter.set_hp( 0 );
12762 }
void remove_zombie(const monster &critter)
Definition: game.cpp:5285
bool is_hallucination() const override
Definition: monster.cpp:3460
void on_unload()
Do some cleanup and caching as monster is being unloaded from map.
Definition: monster.cpp:3853
void set_hp(int hp)
Directly set the current hp of the monster (not capped at the maximal hp).
Definition: monster.cpp:2164
void despawn_monster(const monster &critter)
Despawn the monster back onto the overmap.

References overmapbuffer::despawn_monster(), monster::is_hallucination(), monster::on_unload(), overmap_buffer, remove_zombie(), and monster::set_hp().

Referenced by place_player_overmap(), and shift_monsters().

◆ despawn_nonlocal_monsters()

void game::despawn_nonlocal_monsters ( )

Definition at line 12764 of file game.cpp.

12765 {
12766  for( monster &critter : g->all_monsters() ) {
12767  if( critter.posx() < 0 - MAPSIZE_X / 6 ||
12768  critter.posy() < 0 - MAPSIZE_Y / 6 ||
12769  critter.posx() > ( MAPSIZE_X * 7 ) / 6 ||
12770  critter.posy() > ( MAPSIZE_Y * 7 ) / 6 ) {
12771  g->despawn_monster( critter );
12772  }
12773  }
12774 }
constexpr int MAPSIZE_Y
constexpr int MAPSIZE_X

References g, MAPSIZE_X, and MAPSIZE_Y.

◆ disable_robot()

bool game::disable_robot ( const tripoint p)

If there is a robot (that can be disabled), query the player and try to disable it.

Returns
true if the robot has been disabled or a similar action has been done. false if the player did not choose any action and the function has effectively done nothing.

Definition at line 10373 of file game.cpp.

10374 {
10375  monster *const mon_ptr = get_creature_tracker().creature_at<monster>( p );
10376  if( !mon_ptr ) {
10377  return false;
10378  }
10379  monster &critter = *mon_ptr;
10381  return false;
10382  }
10383 
10384  const mtype_id mid = critter.type->id;
10385  const itype_id mon_item_id = critter.type->revert_to_itype;
10386  if( !mon_item_id.is_empty() &&
10387  query_yn( _( "Deactivate the %s?" ), critter.name() ) ) {
10389  u.assign_activity( actor );
10390  return true;
10391  }
10392  // Manhacks are special, they have their own menu here.
10393  if( mid == mon_manhack ) {
10394  int choice = UILIST_CANCEL;
10395  if( critter.has_effect( effect_docile ) ) {
10396  choice = uilist( _( "Reprogram the manhack?" ), { _( "Engage targets." ) } );
10397  } else {
10398  choice = uilist( _( "Reprogram the manhack?" ), { _( "Follow me." ) } );
10399  }
10400 
10401  if( choice == 0 ) {
10403  }
10404  }
10405  return false;
10406 }
static bool can_disable_or_reprogram(const monster &monster)
Returns whether the given monster is a robot and can currently be disabled or reprogrammed.
bool is_empty() const
Returns whether this id is empty.
Definition: string_id.h:303
static const efftype_id effect_docile("docile")
static const mtype_id mon_manhack("mon_manhack")
itype_id revert_to_itype
If this is not empty, the monster can be converted into an item of this type (if it's friendly).
Definition: mtype.h:323
const int UILIST_CANCEL
Definition: ui.h:35

References _, Character::assign_activity(), disable_activity_actor::can_disable_or_reprogram(), creature_tracker::creature_at(), effect_docile, get_creature_tracker, disable_activity_actor::get_disable_turns(), Creature::has_effect(), mtype::id, string_id< T >::is_empty(), mon_manhack, monster::name(), query_yn(), mtype::revert_to_itype, monster::type, u, and UILIST_CANCEL.

Referenced by examine().

◆ disp_NPC_epilogues()

void game::disp_NPC_epilogues ( )
private

Definition at line 3612 of file game.cpp.

3613 {
3614  // TODO: This search needs to be expanded to all NPCs
3615  for( character_id elem : follower_ids ) {
3617  if( !guy ) {
3618  continue;
3619  }
3620  const auto new_win = []() {
3622  point( std::max( 0, ( TERMX - FULL_SCREEN_WIDTH ) / 2 ),
3623  std::max( 0, ( TERMY - FULL_SCREEN_HEIGHT ) / 2 ) ) );
3624  };
3625  scrollable_text( new_win, guy->disp_name(), guy->get_epilogue() );
3626  }
3627 }
shared_ptr_fast< npc > find_npc(character_id id)
Find the npc with the given ID.
void scrollable_text(const std::function< catacurses::window()> &init_window, const std::string &title, const std::string &text)
Definition: output.cpp:432

References overmapbuffer::find_npc(), follower_ids, FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, max(), catacurses::newwin(), overmap_buffer, point, scrollable_text(), TERMX, and TERMY.

Referenced by death_screen().

◆ disp_NPCs()

void game::disp_NPCs ( )

Definition at line 3663 of file game.cpp.

3664 {
3665  const tripoint_abs_omt ppos = u.global_omt_location();
3666  const tripoint lpos = u.pos();
3667  const int scan_range = 120;
3668  std::vector<shared_ptr_fast<npc>> npcs = overmap_buffer.get_npcs_near_player( scan_range );
3669  std::sort( npcs.begin(), npcs.end(), npc_dist_to_player() );
3670 
3672  ui_adaptor ui;
3673  ui.on_screen_resize( [&]( ui_adaptor & ui ) {
3676  TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 : 0 ) );
3677  ui.position_from_window( w );
3678  } );
3679  ui.mark_resize();
3680  ui.on_redraw( [&]( const ui_adaptor & ) {
3681  werase( w );
3682  mvwprintz( w, point_zero, c_white, _( "Your overmap position: %s" ), ppos.to_string() );
3683  // NOLINTNEXTLINE(cata-use-named-point-constants)
3684  mvwprintz( w, point( 0, 1 ), c_white, _( "Your local position: %s" ), lpos.to_string() );
3685  size_t i;
3686  int static_npc_count = 0;
3687  for( i = 0; i < npcs.size(); i++ ) {
3688  if(
3689  npcs[i]->has_trait( trait_NPC_STARTING_NPC ) || npcs[i]->has_trait( trait_NPC_STATIC_NPC ) ) {
3690  static_npc_count++;
3691  }
3692  }
3693  mvwprintz( w, point( 0, 2 ), c_white, _( "Total NPCs within %d OMTs: %d. %d are static NPCs." ),
3694  scan_range, npcs.size(), static_npc_count );
3695  for( i = 0; i < 20 && i < npcs.size(); i++ ) {
3696  const tripoint_abs_omt apos = npcs[i]->global_omt_location();
3697  mvwprintz( w, point( 0, i + 4 ), c_white, "%s: %s", npcs[i]->get_name(),
3698  apos.to_string() );
3699  }
3700  for( const monster &m : all_monsters() ) {
3701  mvwprintz( w, point( 0, i + 4 ), c_white, "%s: %d, %d, %d", m.name(),
3702  m.posx(), m.posy(), m.posz() );
3703  ++i;
3704  }
3705  wnoutrefresh( w );
3706  } );
3707 
3708  input_context ctxt( "DISP_NPCS" );
3709  ctxt.register_action( "CONFIRM" );
3710  ctxt.register_action( "QUIT" );
3711  ctxt.register_action( "HELP_KEYBINDINGS" );
3712  bool stop = false;
3713  while( !stop ) {
3715  const std::string action = ctxt.handle_input();
3716  if( action == "CONFIRM" || action == "QUIT" ) {
3717  stop = true;
3718  }
3719  }
3720 }
tripoint_abs_omt global_omt_location() const
Returns the location of the creature in global overmap terrain coordinates.
Definition: creature.cpp:3242
std::string to_string() const
Definition: coordinates.h:121
monster_range all_monsters()
Same as all_creatures but iterators only over monsters.
Definition: game.cpp:13228
Represents a context in which a set of actions can be performed.
Definition: input_context.h:40
std::string name(const tripoint &p)
Definition: map.cpp:1684
static const trait_id trait_NPC_STATIC_NPC("NPC_STATIC_NPC")
void wnoutrefresh(const window &win)
Definition: ncurses_def.cpp:67
void werase(const window &win)
Definition: ncurses_def.cpp:83
std::string to_string() const
Definition: point.cpp:79

References _, action, all_monsters(), c_white, FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, overmapbuffer::get_npcs_near_player(), Creature::global_omt_location(), input_context::handle_input(), m, mvwprintz(), map::name(), catacurses::newwin(), overmap_buffer, point, point_zero, Creature::pos(), ui_manager::redraw(), input_context::register_action(), TERMX, TERMY, coords::coord_point_base< Point >::to_string(), tripoint::to_string(), trait_NPC_STARTING_NPC, trait_NPC_STATIC_NPC, u, catacurses::werase(), and catacurses::wnoutrefresh().

◆ display_faction_epilogues()

void game::display_faction_epilogues ( )
private

Definition at line 3629 of file game.cpp.

3630 {
3631  for( const auto &elem : faction_manager_ptr->all() ) {
3632  if( elem.second.known_by_u ) {
3633  const std::vector<std::string> epilogue = elem.second.epilogue();
3634  if( !epilogue.empty() ) {
3635  const auto new_win = []() {
3637  point( std::max( 0, ( TERMX - FULL_SCREEN_WIDTH ) / 2 ),
3638  std::max( 0, ( TERMY - FULL_SCREEN_HEIGHT ) / 2 ) ) );
3639  };
3640  scrollable_text( new_win, elem.second.name,
3641  std::accumulate( epilogue.begin() + 1, epilogue.end(), epilogue.front(),
3642  []( std::string lhs, const std::string & rhs ) -> std::string {
3643  return std::move( lhs ) + "\n" + rhs;
3644  } ) );
3645  }
3646  }
3647  }
3648 }
pimpl< faction_manager > faction_manager_ptr
Definition: game.h:1100

References faction_manager_ptr, FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, max(), catacurses::newwin(), point, scrollable_text(), TERMX, and TERMY.

Referenced by death_screen().

◆ display_lighting()

void game::display_lighting ( )
private

Definition at line 12998 of file game.cpp.

12999 {
13000  if( use_tiles ) {
13002  if( !g->display_overlay_state( ACTION_DISPLAY_LIGHTING ) ) {
13003  return;
13004  }
13005  uilist lighting_menu;
13006  std::vector<std::string> lighting_menu_strings{
13007  "Global lighting conditions"
13008  };
13009 
13010  int count = 0;
13011  for( const auto &menu_str : lighting_menu_strings ) {
13012  lighting_menu.addentry( count++, true, MENU_AUTOASSIGN, "%s", menu_str );
13013  }
13014 
13015  lighting_menu.w_y_setup = 0;
13016  lighting_menu.query();
13017  if( ( lighting_menu.ret >= 0 ) &&
13018  ( static_cast<size_t>( lighting_menu.ret ) < lighting_menu_strings.size() ) ) {
13019  g->displaying_lighting_condition = lighting_menu.ret;
13020  }
13021  }
13022 }
@ ACTION_DISPLAY_LIGHTING
Toggle lighting conditions map.
Definition: action.h:341
bool use_tiles
void display_toggle_overlay(action_id)
Definition: game.cpp:12894
pos_scalar w_y_setup
Definition: ui.h:437
const int MENU_AUTOASSIGN
Definition: ui.h:38

References ACTION_DISPLAY_LIGHTING, uilist::addentry(), display_toggle_overlay(), g, MENU_AUTOASSIGN, uilist::query(), uilist::ret, use_tiles, and uilist::w_y_setup.

Referenced by do_regular_action(), and look_around().

◆ display_om_pathfinding_progress()

void game::display_om_pathfinding_progress ( size_t  open_set,
size_t  known_size 
)
static

Definition at line 12879 of file game.cpp.

12880 {
12882  static_popup pop;
12883  pop.on_top( true ).wait_message( "%s", _( "Hang on a bit…" ) );
12885  refresh_display();
12887 }
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
query_popup & wait_message(const nc_color &bar_color, const std::string &fmt, Args &&... args)
Like query_popup::message, but with waiting symbol prepended to the text.
Definition: popup.h:106
query_popup & on_top(bool top)
Whether to show the popup on the top of the screen.
Definition: popup.cpp:191
Create a popup on the UI stack that gets displayed but receives no input itself.
Definition: popup.h:272
input_manager inp_mngr
Definition: input.cpp:161

References _, inp_mngr, query_popup::on_top(), input_manager::pump_events(), ui_manager::redraw(), refresh_display(), and query_popup::wait_message().

◆ display_overlay_state()

bool game::display_overlay_state ( action_id  action)

Definition at line 12889 of file game.cpp.

12890 {
12892 }
std::optional< action_id > displaying_overlays
Definition: game.h:1029

References action, and displaying_overlays.

Referenced by display_toggle_overlay(), and display_visibility().

◆ display_radiation()

void game::display_radiation ( )
private

Definition at line 13024 of file game.cpp.

13025 {
13026  if( use_tiles ) {
13028  }
13029 }
@ ACTION_DISPLAY_RADIATION
Toggle radiation map.
Definition: action.h:343

References ACTION_DISPLAY_RADIATION, display_toggle_overlay(), and use_tiles.

Referenced by do_regular_action(), and look_around().

◆ display_scent()

void game::display_scent ( )
private

Definition at line 12903 of file game.cpp.

12904 {
12905  if( use_tiles ) {
12907  } else {
12908  int div;
12909  bool got_value = query_int( div, _( "Set the Scent Map sensitivity to (0 to cancel)?" ) );
12910  if( !got_value || div < 1 ) {
12911  add_msg( _( "Never mind." ) );
12912  return;
12913  }
12914  shared_ptr_fast<game::draw_callback_t> scent_cb = make_shared_fast<game::draw_callback_t>( [&]() {
12915  scent.draw( w_terrain, div * 2, u.pos() + u.view_offset );
12916  } );
12917  g->add_draw_callback( scent_cb );
12918 
12921  }
12922 }
@ ACTION_DISPLAY_SCENT
Toggle scent map.
Definition: action.h:303
tripoint view_offset
Definition: character.h:2705
void wait_for_any_key()
Wait until the user presses a key.
Definition: input.cpp:893
void draw(const catacurses::window &win, int div, const tripoint &center) const
Definition: scent_map.cpp:71
constexpr double div(double l, double r)
bool query_int(int &result, const std::string &text)
Definition: output.cpp:880

References _, ACTION_DISPLAY_SCENT, add_msg(), display_toggle_overlay(), math_opers::div(), scent_map::draw(), g, inp_mngr, Creature::pos(), query_int(), ui_manager::redraw(), scent, u, use_tiles, Character::view_offset, w_terrain, and input_manager::wait_for_any_key().

Referenced by do_regular_action(), and look_around().

◆ display_temperature()

void game::display_temperature ( )
private

Definition at line 12924 of file game.cpp.

12925 {
12926  if( use_tiles ) {
12928  }
12929 }
@ ACTION_DISPLAY_TEMPERATURE
Toggle temperature map.
Definition: action.h:335

References ACTION_DISPLAY_TEMPERATURE, display_toggle_overlay(), and use_tiles.

Referenced by do_regular_action(), and look_around().

◆ display_toggle_overlay()

void game::display_toggle_overlay ( action_id  action)

Definition at line 12894 of file game.cpp.

12895 {
12896  if( display_overlay_state( action ) ) {
12897  displaying_overlays.reset();
12898  } else {
12900  }
12901 }
bool display_overlay_state(action_id)
Definition: game.cpp:12889

References action, display_overlay_state(), and displaying_overlays.

Referenced by display_lighting(), display_radiation(), display_scent(), display_temperature(), display_transparency(), display_vehicle_ai(), and display_visibility().

◆ display_transparency()

void game::display_transparency ( )
private

Definition at line 13031 of file game.cpp.

13032 {
13033  if( use_tiles ) {
13035  }
13036 }
@ ACTION_DISPLAY_TRANSPARENCY
Toggle transparency map.
Definition: action.h:345

References ACTION_DISPLAY_TRANSPARENCY, display_toggle_overlay(), and use_tiles.

Referenced by do_regular_action(), and look_around().

◆ display_vehicle_ai()

void game::display_vehicle_ai ( )
private

Definition at line 12931 of file game.cpp.

12932 {
12933  if( use_tiles ) {
12935  }
12936 }
@ ACTION_DISPLAY_VEHICLE_AI
Toggle vehicle autopilot data.
Definition: action.h:337

References ACTION_DISPLAY_VEHICLE_AI, display_toggle_overlay(), and use_tiles.

Referenced by do_regular_action().

◆ display_visibility()

void game::display_visibility ( )
private

Definition at line 12938 of file game.cpp.

12939 {
12940  if( use_tiles ) {
12943  std::vector< tripoint > locations;
12944  uilist creature_menu;
12945  int num_creatures = 0;
12946  creature_menu.addentry( num_creatures++, true, MENU_AUTOASSIGN, "%s", _( "You" ) );
12947  locations.emplace_back( get_player_character().pos() ); // add player first.
12948  for( const Creature &critter : g->all_creatures() ) {
12949  if( critter.is_avatar() ) {
12950  continue;
12951  }
12952  creature_menu.addentry( num_creatures++, true, MENU_AUTOASSIGN, critter.disp_name() );
12953  locations.emplace_back( critter.pos() );
12954  }
12955 
12956  pointmenu_cb callback( locations );
12957  creature_menu.callback = &callback;
12958  creature_menu.w_y_setup = 0;
12959  creature_menu.query();
12960  if( creature_menu.ret >= 0 && static_cast<size_t>( creature_menu.ret ) < locations.size() ) {
12963  }
12964  } else {
12966  }
12967  }
12968 }
@ ACTION_DISPLAY_VISIBILITY
Toggle visibility map.
Definition: action.h:339
size_t num_creatures() const
Returns the approximate number of creatures in the reality bubble.
Definition: game.cpp:5273
Creature * displaying_visibility_creature
Creature for which to display the visibility map.
Definition: game.h:1131
Callback for uilist that pairs menu entries with points When an entry is selected,...
Definition: ui.h:576
uilist_callback * callback
Definition: ui.h:434
generic_factory< overmap_location > locations("overmap location")

References _, ACTION_DISPLAY_VISIBILITY, uilist::addentry(), uilist::callback, creature, creature_tracker::creature_at(), display_overlay_state(), display_toggle_overlay(), displaying_visibility_creature, g, get_creature_tracker, get_player_character, anonymous_namespace{overmap_location.cpp}::locations, MENU_AUTOASSIGN, num_creatures(), math_opers::pos(), uilist::query(), uilist::ret, use_tiles, and uilist::w_y_setup.

Referenced by do_regular_action().

◆ do_regular_action()

bool game::do_regular_action ( action_id act,
avatar player_character,
const std::optional< tripoint > &  mouse_target 
)
private

Definition at line 2111 of file handle_action.cpp.

2113 {
2114  item_location weapon = player_character.get_wielded_item();
2115  const bool in_shell = player_character.has_active_mutation( trait_SHELL2 )
2116  || player_character.has_active_mutation( trait_SHELL3 );
2117 
2118  const std::map<action_id, std::string> actions_disabled_mounted = get_actions_disabled_mounted();
2119  const std::map<action_id, std::string> actions_disabled_in_shell = get_actions_disabled_in_shell();
2120 
2121  if( in_shell && actions_disabled_in_shell.count( act ) > 0 ) {
2122  add_msg( m_info, actions_disabled_in_shell.at( act ) );
2123  return true;
2124  }
2125 
2127  add_msg( m_info, _( "You lack the substance to affect anything." ) );
2128  return true;
2129  }
2130 
2131  if( player_character.is_mounted() && actions_disabled_mounted.count( act ) > 0 ) {
2132  add_msg( m_info, actions_disabled_mounted.at( act ) );
2133  return true;
2134  }
2135 
2136  switch( act ) {
2137  case ACTION_NULL: // dummy entry
2138  case NUM_ACTIONS: // dummy entry
2139  case ACTION_ACTIONMENU: // handled above
2140  case ACTION_MAIN_MENU:
2141  case ACTION_KEYBINDINGS:
2142  break;
2143 
2144  case ACTION_TIMEOUT:
2145  if( check_safe_mode_allowed( false ) ) {
2146  player_character.pause();
2147  }
2148  break;
2149 
2150  case ACTION_PAUSE:
2151  if( check_safe_mode_allowed() ) {
2152  player_character.pause();
2153  }
2154  break;
2155 
2156  case ACTION_CYCLE_MOVE:
2157  player_character.cycle_move_mode();
2158  break;
2159 
2161  player_character.cycle_move_mode_reverse();
2162  break;
2163 
2164  case ACTION_RESET_MOVE:
2165  player_character.reset_move_mode();
2166  break;
2167 
2168  case ACTION_TOGGLE_RUN:
2169  player_character.toggle_run_mode();
2170  break;
2171 
2172  case ACTION_TOGGLE_CROUCH:
2173  player_character.toggle_crouch_mode();
2174  break;
2175 
2176  case ACTION_TOGGLE_PRONE:
2177  player_character.toggle_prone_mode();
2178  break;
2179 
2180  case ACTION_OPEN_MOVEMENT:
2182  break;
2183 
2184  case ACTION_MOVE_FORTH:
2186  case ACTION_MOVE_RIGHT:
2188  case ACTION_MOVE_BACK:
2189  case ACTION_MOVE_BACK_LEFT:
2190  case ACTION_MOVE_LEFT:
2192  if( !player_character.get_value( "remote_controlling" ).empty() &&
2193  ( player_character.has_active_item( itype_radiocontrol ) ||
2194  player_character.has_active_bionic( bio_remote ) ) ) {
2196  } else if( has_vehicle_control( player_character ) ) {
2197  // vehicle control uses x for steering and y for ac/deceleration,
2198  // so no rotation needed
2200  } else {
2202  if( auto_travel_mode && !player_character.is_auto_moving() ) {
2203  for( int i = 0; i < SEEX; i++ ) {
2204  tripoint_bub_ms auto_travel_destination =
2205  player_character.pos_bub() + dest_delta * ( SEEX - i );
2207  m.route( player_character.pos_bub(), auto_travel_destination,
2208  player_character.get_pathfinding_settings(),
2209  player_character.get_path_avoid() );
2210  if( !destination_preview.empty() ) {
2211  destination_preview.erase(
2212  destination_preview.begin() + 1, destination_preview.end() );
2213  player_character.set_destination( destination_preview );
2214  break;
2215  }
2216  }
2217  act = player_character.get_next_auto_move_direction();
2219  if( dest_next == point_zero ) {
2220  player_character.clear_destination();
2221  }
2222  dest_delta = dest_next;
2223  }
2224  if( !avatar_action::move( player_character, m, dest_delta ) ) {
2225  // auto-move should be canceled due to a failed move or obstacle
2226  player_character.clear_destination();
2227  }
2228 
2229  if( get_option<bool>( "AUTO_FEATURES" ) && get_option<bool>( "AUTO_MOPPING" ) &&
2230  weapon && weapon->has_flag( json_flag_MOP ) ) {
2231  map &here = get_map();
2232  const bool is_blind = player_character.is_blind();
2233  for( const tripoint_bub_ms &point : here.points_in_radius( player_character.pos_bub(), 1 ) ) {
2234  bool did_mop = false;
2235  if( is_blind ) {
2236  // blind character have a 1/3 chance of actually mopping
2237  if( one_in( 3 ) ) {
2238  did_mop = here.mop_spills( point );
2239  } else {
2240  did_mop = here.terrain_moppable( point );
2241  }
2242  } else {
2243  did_mop = here.mop_spills( point );
2244  }
2245  // iuse::mop costs 15 moves per use
2246  if( did_mop ) {
2247  player_character.mod_moves( -15 );
2248  }
2249  }
2250  }
2251  }
2252  break;
2253  case ACTION_MOVE_DOWN: {
2254  if( player_character.is_mounted() ) {
2255  auto *mon = player_character.mounted_creature.get();
2256  if( !mon->has_flag( mon_flag_RIDEABLE_MECH ) ) {
2257  add_msg( m_info, _( "You can't go down stairs while you're riding." ) );
2258  break;
2259  }
2260  }
2261 
2262  if( has_vehicle_control( player_character ) ) {
2263  const optional_vpart_position vp = get_map().veh_at( player_character.pos() );
2264  if( vp->vehicle().is_rotorcraft() ) {
2266  break;
2267  }
2268  }
2269 
2270  if( !player_character.in_vehicle ) {
2271  // We're NOT standing on tiles with stairs, ropes, ladders etc
2272  if( !m.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, player_character.pos() ) ) {
2273  std::vector<tripoint> pts;
2274 
2275  // Check tiles around player character for open air
2276  for( const tripoint &p : m.points_in_radius( player_character.pos(), 1 ) ) {
2278  pts.push_back( p );
2279  }
2280  }
2281 
2282  // If we found tiles with open air, prompt player with query on direction they want to climb
2283  if( !pts.empty() ) {
2284  const std::optional<tripoint> pnt = point_selection_menu( pts, false );
2285  if( !pnt ) {
2286  break;
2287  }
2288 
2289  // If player selected direction, climb down there, and exit from the whole ACTION_MOVE_DOWN case
2290  climb_down( *pnt );
2291  break;
2292  }
2293  }
2294 
2295  // If we're here, we might or might not be standing on tiles with stairs, ropes, ladders etc
2296  // In any case, attempt a descend
2297  vertical_move( -1, false );
2298  }
2299  break;
2300  }
2301 
2302  case ACTION_MOVE_UP:
2303  if( player_character.is_mounted() ) {
2304  auto *mon = player_character.mounted_creature.get();
2305  if( !mon->has_flag( mon_flag_RIDEABLE_MECH ) ) {
2306  add_msg( m_info, _( "You can't go up stairs while you're riding." ) );
2307  break;
2308  }
2309  }
2310  if( !player_character.in_vehicle ) {
2311  vertical_move( 1, false );
2312  } else if( has_vehicle_control( player_character ) ) {
2313  const optional_vpart_position vp = get_map().veh_at( player_character.pos() );
2314  if( vp->vehicle().is_rotorcraft() ) {
2316  }
2317  }
2318  break;
2319 
2320  case ACTION_OPEN:
2321  open();
2322  break;
2323 
2324  case ACTION_CLOSE:
2325  if( player_character.is_mounted() ) {
2326  auto *mon = player_character.mounted_creature.get();
2327  if( !mon->has_flag( mon_flag_RIDEABLE_MECH ) ) {
2328  add_msg( m_info, _( "You can't close things while you're riding." ) );
2329  }
2330  } else if( mouse_target ) {
2331  doors::close_door( m, player_character, tripoint_bub_ms( *mouse_target ) );
2332  } else {
2333  close();
2334  }
2335  break;
2336 
2337  case ACTION_SMASH:
2338  if( has_vehicle_control( player_character ) ) {
2339  handbrake();
2340  } else {
2341  smash();
2342  }
2343  break;
2344 
2345  case ACTION_EXAMINE:
2347  if( mouse_target ) {
2348  // Examine including item pickup if ACTION_EXAMINE_AND_PICKUP is used
2349  examine( *mouse_target, act == ACTION_EXAMINE_AND_PICKUP );
2350  } else {
2352  }
2353  break;
2354 
2355  case ACTION_ADVANCEDINV:
2357  break;
2358 
2359  case ACTION_PICKUP:
2360  case ACTION_PICKUP_ALL:
2361  if( mouse_target ) {
2362  pickup( *mouse_target );
2363  } else {
2364  if( act == ACTION_PICKUP_ALL ) {
2365  pickup_all();
2366  } else {
2367  pickup();
2368  }
2369  }
2370  break;
2371 
2372  case ACTION_GRAB:
2373  grab();
2374  break;
2375 
2376  case ACTION_HAUL:
2377  haul();
2378  break;
2379 
2380  case ACTION_HAUL_TOGGLE:
2381  haul_toggle();
2382  break;
2383 
2384  case ACTION_BUTCHER:
2385  butcher();
2386  break;
2387 
2388  case ACTION_CHAT:
2389  chat();
2390  break;
2391 
2392  case ACTION_PEEK:
2393  peek();
2394  break;
2395 
2396  case ACTION_LIST_ITEMS:
2398  break;
2399 
2400  case ACTION_ZONES:
2401  zones_manager();
2402  break;
2403 
2404  case ACTION_LOOT:
2405  loot();
2406  break;
2407 
2408  case ACTION_INVENTORY:
2409  game_menus::inv::common( player_character );
2410  break;
2411 
2412  case ACTION_COMPARE:
2413  game_menus::inv::compare( player_character, std::nullopt );
2414  break;
2415 
2416  case ACTION_ORGANIZE:
2417  game_menus::inv::swap_letters( player_character );
2418  break;
2419 
2420  case ACTION_USE:
2421  // Shell-users are presumed to be able to mess with their inventories, etc
2422  // while in the shell. Eating, gear-changing, and item use are OK.
2423  avatar_action::use_item( player_character );
2424  break;
2425 
2426  case ACTION_USE_WIELDED:
2427  player_character.use_wielded();
2428  break;
2429 
2430  case ACTION_WEAR:
2431  wear();
2432  break;
2433 
2434  case ACTION_TAKE_OFF:
2435  takeoff();
2436  break;
2437 
2438  case ACTION_EAT:
2439  if( !avatar_action::eat_here( player_character ) ) {
2440  avatar_action::eat_or_use( player_character, game_menus::inv::consume( player_character ) );
2441  }
2442  break;
2443 
2444  case ACTION_OPEN_CONSUME:
2445  if( !avatar_action::eat_here( player_character ) ) {
2447  }
2448  break;
2449 
2450  case ACTION_READ:
2451  // Shell-users are presumed to have the book just at an opening and read it that way
2452  read();
2453  break;
2454 
2455  case ACTION_WIELD:
2456  wield();
2457  break;
2458 
2459  case ACTION_PICK_STYLE:
2460  player_character.martial_arts_data->pick_style( player_character );
2461  break;
2462 
2463  case ACTION_RELOAD_ITEM:
2464  reload_item();
2465  break;
2466 
2467  case ACTION_RELOAD_WEAPON:
2468  reload_weapon();
2469  break;
2470 
2471  case ACTION_RELOAD_WIELDED:
2472  reload_wielded();
2473  break;
2474 
2475  case ACTION_UNLOAD:
2476  avatar_action::unload( player_character );
2477  break;
2478 
2479  case ACTION_MEND:
2480  avatar_action::mend( player_character, item_location() );
2481  break;
2482 
2483  case ACTION_THROW: {
2484  item_location loc;
2485  avatar_action::plthrow( player_character, loc );
2486  break;
2487  }
2488 
2489  case ACTION_FIRE:
2490  fire();
2491  break;
2492 
2493  case ACTION_CAST_SPELL:
2494  cast_spell();
2495  break;
2496 
2497  case ACTION_FIRE_BURST: {
2498  if( weapon ) {
2499  gun_mode_id original_mode = weapon->gun_get_mode_id();
2500  if( weapon->gun_set_mode( gun_mode_AUTO ) ) {
2501  avatar_action::fire_wielded_weapon( player_character );
2502  weapon->gun_set_mode( original_mode );
2503  }
2504  }
2505  break;
2506  }
2507 
2509  if( weapon && weapon->is_gun() && !weapon->is_gunmod() ) {
2510  if( weapon->gun_all_modes().size() > 1 ) {
2511  weapon->gun_cycle_mode();
2512  } else {
2513  add_msg( m_info, _( "Your %s has only one firing mode." ), weapon->tname() );
2514  }
2515  }
2516  break;
2517 
2519  if( weapon && weapon->is_gun() && !weapon->is_gunmod() ) {
2520  if( weapon->has_flag( flag_RELOAD_ONE ) ||
2521  weapon->has_flag( flag_RELOAD_AND_SHOOT ) ) {
2522  item::reload_option opt = player_character.select_ammo( weapon, false );
2523  if( !opt ) {
2524  break;
2525  } else if( player_character.ammo_location && opt.ammo == player_character.ammo_location ) {
2526  player_character.add_msg_if_player( _( "Cleared ammo preferences for %s." ), weapon->tname() );
2527  player_character.ammo_location = item_location();
2528  } else if( player_character.has_item( *opt.ammo ) ) {
2529  player_character.add_msg_if_player( _( "Selected %s as default ammo for %s." ), opt.ammo->tname(),
2530  weapon->tname() );
2531  player_character.ammo_location = opt.ammo;
2532  } else {
2533  player_character.add_msg_if_player(
2534  _( "You need to keep that ammo on you to select it as default ammo." ) );
2535  }
2536  }
2537  }
2538  break;
2539 
2540  case ACTION_INSERT_ITEM:
2541  insert_item();
2542  break;
2543 
2545  // You CAN drop things to your own tile while in the shell.
2546  unload_container();
2547  break;
2548 
2549  case ACTION_DROP:
2550  drop_in_direction( player_character.pos() );
2551  break;
2552  case ACTION_DIR_DROP:
2553  if( const std::optional<tripoint> pnt = choose_adjacent( _( "Drop where?" ) ) ) {
2554  if( *pnt != player_character.pos() && in_shell ) {
2555  add_msg( m_info, _( "You can't drop things to another tile while you're in your shell." ) );
2556  } else {
2557  drop_in_direction( *pnt );
2558  }
2559  }
2560  break;
2561  case ACTION_BIONICS:
2562  player_character.power_bionics();
2563  break;
2564  case ACTION_MUTATIONS:
2565  player_character.power_mutations();
2566  break;
2567 
2568  case ACTION_SORT_ARMOR:
2569  player_character.worn.sort_armor( player_character );
2570  break;
2571 
2572  case ACTION_WAIT:
2573  wait();
2574  break;
2575 
2576  case ACTION_CRAFT:
2577  player_character.craft();
2578  break;
2579 
2580  case ACTION_RECRAFT:
2581  player_character.recraft();
2582  break;
2583 
2584  case ACTION_LONGCRAFT:
2585  player_character.long_craft();
2586  break;
2587 
2588  case ACTION_DISASSEMBLE:
2589  if( player_character.controlling_vehicle ) {
2590  add_msg( m_info, _( "You can't disassemble items while driving." ) );
2591  } else {
2592  player_character.disassemble();
2593  }
2594  break;
2595 
2596  case ACTION_CONSTRUCT:
2597  if( player_character.in_vehicle ) {
2598  add_msg( m_info, _( "You can't construct while in a vehicle." ) );
2599  } else {
2600  construction_menu( false );
2601  }
2602  break;
2603 
2604  case ACTION_SLEEP:
2605  if( has_vehicle_control( player_character ) ) {
2606  add_msg( m_info, _( "You can't sleep while controlling a vehicle" ) );
2607  } else {
2608  sleep();
2609  }
2610  break;
2611 
2613  if( player_character.is_mounted() ) {
2614  player_character.dismount();
2615  } else if( player_character.has_trait( trait_WAYFARER ) ) {
2616  add_msg( m_info, _( "You refuse to take control of this vehicle." ) );
2617  } else {
2618  control_vehicle();
2619  }
2620  break;
2621 
2624  add_msg( m_info, auto_travel_mode ? _( "Auto travel mode ON!" ) : _( "Auto travel mode OFF!" ) );
2625  break;
2626 
2628  if( safe_mode == SAFE_MODE_OFF ) {
2630  mostseen = 0;
2631  add_msg( m_info, _( "Safe mode ON!" ) );
2632  } else {
2633  turnssincelastmon = 0_turns;
2635  add_msg( m_info, get_option<bool>( "AUTOSAFEMODE" )
2636  ? _( "Safe mode OFF! (Auto safe mode still enabled!)" ) : _( "Safe mode OFF!" ) );
2637  }
2638  if( player_character.has_effect( effect_laserlocked ) ) {
2639  player_character.remove_effect( effect_laserlocked );
2640  safe_mode_warning_logged = false;
2641  }
2642  break;
2643 
2644  case ACTION_TOGGLE_AUTOSAFE: {
2645  options_manager::cOpt &autosafemode_option = get_options().get_option( "AUTOSAFEMODE" );
2646  add_msg( m_info, autosafemode_option.value_as<bool>()
2647  ? _( "Auto safe mode OFF!" ) : _( "Auto safe mode ON!" ) );
2648  autosafemode_option.setNext();
2649  break;
2650  }
2651 
2652  case ACTION_IGNORE_ENEMY:
2653  if( safe_mode == SAFE_MODE_STOP ) {
2654  add_msg( m_info, _( "Ignoring enemy!" ) );
2655  for( auto &elem : player_character.get_mon_visible().new_seen_mon ) {
2656  monster &critter = *elem;
2657  critter.ignoring = rl_dist( player_character.pos(), critter.pos() );
2658  }
2660  } else if( player_character.has_effect( effect_laserlocked ) ) {
2661  if( player_character.has_trait( trait_PROF_CHURL ) ) {
2662  add_msg( m_warning, _( "You make the sign of the cross." ) );
2663  } else {
2664  add_msg( m_info, _( "Ignoring laser targeting!" ) );
2665  }
2666  player_character.remove_effect( effect_laserlocked );
2667  safe_mode_warning_logged = false;
2668  }
2669  break;
2670 
2672  if( safe_mode == SAFE_MODE_STOP && !get_safemode().empty() ) {
2673  get_safemode().add_rule( get_safemode().lastmon_whitelist, Creature::Attitude::ANY, 0,
2675  add_msg( m_info, _( "Creature whitelisted: %s" ), get_safemode().lastmon_whitelist );
2677  mostseen = 0;
2678  } else {
2679  get_safemode().show();
2680  }
2681  break;
2682 
2683  case ACTION_WORKOUT:
2684  if( query_yn( _( "Start workout?" ) ) ) {
2685  player_character.assign_activity( workout_activity_actor( player_character.pos() ) );
2686  }
2687  break;
2688 
2689  case ACTION_SUICIDE:
2690  if( query_yn( _( "Abandon this character?" ) ) ) {
2691  if( query_yn( _( "This will kill your character. Continue?" ) ) ) {
2692  player_character.set_moves( 0 );
2693  player_character.place_corpse();
2694  uquit = QUIT_SUICIDE;
2695  }
2696  }
2697  break;
2698 
2699  case ACTION_SAVE:
2700  if( query_yn( _( "Save and quit?" ) ) ) {
2701  if( save() ) {
2702  player_character.set_moves( 0 );
2703  uquit = QUIT_SAVED;
2704  }
2705  }
2706  break;
2707 
2708  case ACTION_QUICKSAVE:
2709  quicksave();
2710  return false;
2711 
2712  case ACTION_QUICKLOAD:
2713  quickload();
2714  return false;
2715 
2716  case ACTION_PL_INFO:
2717  player_character.disp_info( true );
2718  break;
2719 
2720  case ACTION_MAP:
2721  if( !m.is_outside( player_character.pos() ) ) {
2723  }
2726  } else {
2727  add_msg( m_info, _( "You have no idea where you are." ) );
2728  }
2729  break;
2730 
2731  case ACTION_SKY:
2732  if( m.is_outside( player_character.pos() ) ) {
2734  } else {
2735  add_msg( m_info, _( "You can't see the sky from here." ) );
2736  }
2737  break;
2738 
2739  case ACTION_MISSIONS:
2740  list_missions();
2741  break;
2742 
2743  case ACTION_DIARY:
2745  break;
2746 
2747  case ACTION_FACTIONS:
2748  faction_manager_ptr->display();
2749  break;
2750 
2751  case ACTION_MORALE:
2752  player_character.disp_morale();
2753  break;
2754 
2755  case ACTION_MEDICAL:
2756  player_character.disp_medical();
2757  break;
2758 
2759  case ACTION_BODYSTATUS:
2761  break;
2762 
2763  case ACTION_MESSAGES:
2765  break;
2766 
2767  case ACTION_HELP:
2768  get_help().display_help();
2769  break;
2770 
2771  case ACTION_OPTIONS:
2772  get_options().show( true );
2773  break;
2774 
2775  case ACTION_AUTOPICKUP:
2776  get_auto_pickup().show();
2777  break;
2778 
2779  case ACTION_AUTONOTES:
2781  break;
2782 
2783  case ACTION_SAFEMODE:
2784  get_safemode().show();
2785  break;
2786 
2789  break;
2790 
2791  case ACTION_COLOR:
2792  all_colors.show_gui();
2793  break;
2794 
2795  case ACTION_WORLD_MODS:
2796  world_generator->show_active_world_mods( world_generator->active_world->active_mod_order );
2797  break;
2798 
2799  case ACTION_DEBUG:
2801  break; //don't do anything when sharing and not debugger
2802  }
2804  break;
2805 
2808  break;
2809 
2812  break;
2813 
2816  break;
2817 
2818  case ACTION_RELOAD_TILESET:
2819  reload_tileset();
2820  break;
2821 
2823  get_options().get_option( "AUTO_FEATURES" ).setNext();
2824  get_options().save();
2825  //~ Auto Features are now ON/OFF
2826  add_msg( _( "%s are now %s." ),
2827  get_options().get_option( "AUTO_FEATURES" ).getMenuText(),
2828  get_option<bool>( "AUTO_FEATURES" ) ? _( "ON" ) : _( "OFF" ) );
2829  break;
2830 
2832  get_options().get_option( "AUTO_PULP_BUTCHER" ).setNext();
2833  get_options().save();
2834  //~ Auto Pulp/Pulp Adjacent/Butcher is now set to x
2835  add_msg( _( "%s is now set to %s." ),
2836  get_options().get_option( "AUTO_PULP_BUTCHER" ).getMenuText(),
2837  get_options().get_option( "AUTO_PULP_BUTCHER" ).getValueName() );
2838  break;
2839 
2841  get_options().get_option( "AUTO_MINING" ).setNext();
2842  get_options().save();
2843  //~ Auto Mining is now ON/OFF
2844  add_msg( _( "%s is now %s." ),
2845  get_options().get_option( "AUTO_MINING" ).getMenuText(),
2846  get_option<bool>( "AUTO_MINING" ) ? _( "ON" ) : _( "OFF" ) );
2847  break;
2848 
2850  if( player_character.get_value( "THIEF_MODE" ) == "THIEF_ASK" ) {
2851  player_character.set_value( "THIEF_MODE", "THIEF_HONEST" );
2852  player_character.set_value( "THIEF_MODE_KEEP", "YES" );
2853  //~ Thief mode cycled between THIEF_ASK/THIEF_HONEST/THIEF_STEAL
2854  add_msg( _( "You will not pick up other peoples belongings." ) );
2855  } else if( player_character.get_value( "THIEF_MODE" ) == "THIEF_HONEST" ) {
2856  player_character.set_value( "THIEF_MODE", "THIEF_STEAL" );
2857  player_character.set_value( "THIEF_MODE_KEEP", "YES" );
2858  //~ Thief mode cycled between THIEF_ASK/THIEF_HONEST/THIEF_STEAL
2859  add_msg( _( "You will pick up also those things that belong to others!" ) );
2860  } else if( player_character.get_value( "THIEF_MODE" ) == "THIEF_STEAL" ) {
2861  player_character.set_value( "THIEF_MODE", "THIEF_ASK" );
2862  player_character.set_value( "THIEF_MODE_KEEP", "NO" );
2863  //~ Thief mode cycled between THIEF_ASK/THIEF_HONEST/THIEF_STEAL
2864  add_msg( _( "You will be reminded not to steal." ) );
2865  } else {
2866  // ERROR
2867  add_msg( _( "THIEF_MODE CONTAINED BAD VALUE [ %s ]!" ),
2868  player_character.get_value( "THIEF_MODE" ) );
2869  }
2870  break;
2871 
2873  get_options().get_option( "AUTO_FORAGING" ).setNext();
2874  get_options().save();
2875  //~ Auto Foraging is now set to x
2876  add_msg( _( "%s is now set to %s." ),
2877  get_options().get_option( "AUTO_FORAGING" ).getMenuText(),
2878  get_options().get_option( "AUTO_FORAGING" ).getValueName() );
2879  break;
2880 
2882  get_options().get_option( "AUTO_PICKUP" ).setNext();
2883  get_options().save();
2884  //~ Auto pickup is now set to x
2885  add_msg( _( "%s is now set to %s." ),
2886  get_options().get_option( "AUTO_PICKUP" ).getMenuText(),
2887  get_options().get_option( "AUTO_PICKUP" ).getValueName() );
2888  break;
2889 
2890  case ACTION_DISPLAY_SCENT:
2893  break; //don't do anything when sharing and not debugger
2894  }
2895  display_scent();
2896  break;
2897 
2900  break; //don't do anything when sharing and not debugger
2901  }
2903  break;
2906  break; //don't do anything when sharing and not debugger
2907  }
2909  break;
2912  break; //don't do anything when sharing and not debugger
2913  }
2915  break;
2916 
2919  break; //don't do anything when sharing and not debugger
2920  }
2921  display_lighting();
2922  break;
2923 
2926  break; //don't do anything when sharing and not debugger
2927  }
2929  break;
2930 
2933  break;
2934 
2937  break; //don't do anything when sharing and not debugger
2938  }
2940  break;
2941 
2944  break; //don't do anything when sharing and not debugger
2945  }
2947  break;
2948 
2950  get_options().get_option( "PREVENT_OCCLUSION" ).setNext();
2951  get_options().save();
2952  break;
2953 
2954  case ACTION_ZOOM_IN:
2955  zoom_in();
2957  break;
2958 
2959  case ACTION_ZOOM_OUT:
2960  zoom_out();
2962  break;
2963 
2964  case ACTION_ITEMACTION:
2965  item_action_menu();
2966  break;
2967 
2968  case ACTION_AUTOATTACK:
2969  avatar_action::autoattack( player_character, m );
2970  break;
2971 
2972  default:
2973  break;
2974  }
2975 
2976  return true;
2977 }
point get_delta_from_movement_action(const action_id act, const iso_rotate rot)
Definition: action.cpp:584
@ ACTION_SAFEMODE
Open safemode manager.
Definition: action.h:287
@ ACTION_PEEK
Peek through something (e.g.
Definition: action.h:131
@ ACTION_OPEN
Open an item (e.g.
Definition: action.h:104
@ ACTION_CRAFT
Open crafting menu.
Definition: action.h:213
@ ACTION_DROP
Open the drop-item menu.
Definition: action.h:195
@ ACTION_READ
Open the read menu.
Definition: action.h:163
@ ACTION_TOGGLE_AUTO_PICKUP
Turn auto pickup on/off.
Definition: action.h:333
@ ACTION_MOVE_BACK_LEFT
Move towards bottom-left of screen / decelerate and steer left.
Definition: action.h:52
@ ACTION_ZOOM_IN
Zoom view out.
Definition: action.h:311
@ ACTION_EAT
Open the default consume item menu.
Definition: action.h:159
@ ACTION_SMASH
Smash something.
Definition: action.h:108
@ ACTION_ADVANCEDINV
Open the advanced inventory screen.
Definition: action.h:145
@ ACTION_EXAMINE_AND_PICKUP
Examine adjacent terrain or furniture, or pick up items.
Definition: action.h:113
@ ACTION_QUICKSAVE
Quicksave the game.
Definition: action.h:245
@ ACTION_HELP
Display help screen.
Definition: action.h:271
@ ACTION_MESSAGES
Display messages screen.
Definition: action.h:269
@ ACTION_ZONES
Open the zone manager.
Definition: action.h:135
@ ACTION_KEYBINDINGS
Display keybindings list.
Definition: action.h:279
@ ACTION_TOGGLE_PIXEL_MINIMAP
Turn pixel minimap on/off.
Definition: action.h:317
@ ACTION_USE
Open the use menu.
Definition: action.h:151
@ ACTION_QUICKLOAD
Quickload the game.
Definition: action.h:247
@ ACTION_LIST_ITEMS
List items and monsters in a given square.
Definition: action.h:133
@ ACTION_WORKOUT
Open workout menu.
Definition: action.h:241
@ ACTION_DEBUG
Open debug menu.
Definition: action.h:301
@ ACTION_OPTIONS
Display options window.
Definition: action.h:281
@ ACTION_MOVE_FORTH
Move towards top of screen / accelerate.
Definition: action.h:42
@ ACTION_PICK_STYLE
Open the martial-arts style menu.
Definition: action.h:167
@ ACTION_CONSTRUCT
Open construct menu.
Definition: action.h:219
@ ACTION_MOVE_FORTH_RIGHT
Move towards top-right of screen / accelerate and steer right.
Definition: action.h:44
@ ACTION_SORT_ARMOR
Open the armor sorting menu.
Definition: action.h:203
@ ACTION_OPEN_CONSUME
Open the custom consume item menu.
Definition: action.h:161
@ ACTION_MORALE
Displays morale menu.
Definition: action.h:265
@ ACTION_NULL
Invalid action used for various lookup errors.
Definition: action.h:23
@ ACTION_RESET_MOVE
Reset movement mode to walk
Definition: action.h:66
@ ACTION_CHAT
Chat with something.
Definition: action.h:127
@ ACTION_RELOAD_WIELDED
Attempt to reload wielded object.
Definition: action.h:173
@ ACTION_MOVE_DOWN
Descend a staircase.
Definition: action.h:58
@ ACTION_MISSIONS
Display missions screen.
Definition: action.h:261
@ ACTION_INSERT_ITEM
Open the insert-item menu.
Definition: action.h:191
@ ACTION_AUTONOTES
Open autonotes manager.
Definition: action.h:285
@ ACTION_WIELD
Open the wield menu.
Definition: action.h:165
@ ACTION_BODYSTATUS
Open body status menu.
Definition: action.h:275
@ ACTION_THROW
Open the throw menu.
Definition: action.h:179
@ ACTION_TOGGLE_AUTO_MINING
Turn auto mining on/off.
Definition: action.h:329
@ ACTION_INVENTORY
Open the primary inventory screen.
Definition: action.h:143
@ ACTION_TOGGLE_AUTOSAFE
Turn automatic triggering of safemode on/off.
Definition: action.h:231
@ ACTION_OPEN_MOVEMENT
Open movement mode menu.
Definition: action.h:74
@ ACTION_COMPARE
Open the item compare screen.
Definition: action.h:147
@ ACTION_BUTCHER
Butcher or disassemble objects in current square.
Definition: action.h:125
@ ACTION_TOGGLE_CROUCH
Toggle crouch on/off.
Definition: action.h:70
@ ACTION_TOGGLE_HOUR_TIMER
Toggle timing of the game hours.
Definition: action.h:350
@ ACTION_CYCLE_MOVE_REVERSE
Cycle run/walk/crouch mode in opposite direction.
Definition: action.h:64
@ ACTION_MAIN_MENU
Display main menu.
Definition: action.h:277
@ ACTION_TOGGLE_PREVENT_OCCLUSION
Toggle retracted/transparent high sprites.
Definition: action.h:347
@ ACTION_WAIT
Open wait menu.
Definition: action.h:211
@ ACTION_ACTIONMENU
Open the action menu.
Definition: action.h:313
@ ACTION_DISASSEMBLE
Open disassemble menu.
Definition: action.h:221
@ ACTION_LOOT
Sort out the loot.
Definition: action.h:137
@ ACTION_TOGGLE_FULLSCREEN
Toggle full-screen mode.
Definition: action.h:299
@ ACTION_MAP
Display over-map.
Definition: action.h:257
@ ACTION_MEND
Open the mending menu (e.g.
Definition: action.h:177
@ ACTION_TOGGLE_THIEF_MODE
Toggle permanent attitude to stealing.
Definition: action.h:233
@ ACTION_USE_WIELDED
Use currently wielded item.
Definition: action.h:153
@ ACTION_UNLOAD_CONTAINER
Unload container in a given direction.
Definition: action.h:193
@ ACTION_MEDICAL
Displays medical menu.
Definition: action.h:267
@ ACTION_PL_INFO
Display player status screen.
Definition: action.h:255
@ ACTION_DISPLAY_SCENT_TYPE
Toggle scent type map.
Definition: action.h:305
@ ACTION_TOGGLE_AUTO_FORAGING
Turn auto foraging on/off.
Definition: action.h:331
@ ACTION_FIRE_BURST
Burst-fire the current weapon.
Definition: action.h:183
@ ACTION_BIONICS
Open the bionics menu.
Definition: action.h:199
@ ACTION_CONTROL_VEHICLE
Open vehicle control menu.
Definition: action.h:225
@ ACTION_HAUL_TOGGLE
Quickly toggle hauling on/off.
Definition: action.h:123
@ ACTION_SAVE
Save the game and quit.
Definition: action.h:243
@ ACTION_MOVE_UP
Ascend a staircase.
Definition: action.h:60
@ ACTION_TOGGLE_PANEL_ADM
Turn admin panel on/off.
Definition: action.h:319
@ ACTION_TOGGLE_AUTO_PULP_BUTCHER
Change auto pulp/butcher mode.
Definition: action.h:327
@ ACTION_TOGGLE_PRONE
Toggle lying down on/off.
Definition: action.h:72
@ ACTION_TOGGLE_AUTO_TRAVEL_MODE
Turn auto travel mode on/off.
Definition: action.h:227
@ ACTION_COLOR
Open color manager.
Definition: action.h:289
@ ACTION_TIMEOUT
Input timeout.
Definition: action.h:40
@ ACTION_TOGGLE_RUN
Toggle run on/off.
Definition: action.h:68
@ ACTION_FACTIONS
Display factions screen.
Definition: action.h:263
@ ACTION_GRAB
Grab or let go of an object.
Definition: action.h:119
@ ACTION_MOVE_BACK
Move towards bottom of screen / decelerate.
Definition: action.h:50
@ ACTION_CAST_SPELL
Cast a spell (only if any spells are known)
Definition: action.h:189
@ ACTION_DIR_DROP
Drop items in a given direction.
Definition: action.h:197
@ ACTION_AUTOATTACK
Auto select and attack hostile creature within range.
Definition: action.h:205
@ ACTION_CYCLE_MOVE
Cycle run/walk/crouch mode.
Definition: action.h:62
@ ACTION_SKY
Show sky state for trying to predict weather.
Definition: action.h:259
@ ACTION_FIRE
Fire the wielded weapon, or open fire menu if none.
Definition: action.h:181
@ ACTION_PAUSE
Pause an on-going activity.
Definition: action.h:38
@ ACTION_MOVE_BACK_RIGHT
Move towards bottom-right of screen / decelerate and steer right.
Definition: action.h:48
@ ACTION_MUTATIONS
Open the mutations menu.
Definition: action.h:201
@ ACTION_HAUL
Haul pile of items, or let go of them.
Definition: action.h:121
@ ACTION_MOVE_RIGHT
Move / steer right.
Definition: action.h:46
@ ACTION_SLEEP
Open sleep menu.
Definition: action.h:223
@ ACTION_ITEMACTION
Open the item uses menu.
Definition: action.h:315
@ ACTION_MOVE_LEFT
Move / steer left.
Definition: action.h:54
@ ACTION_PICKUP_ALL
Pick up items from all current/adjacent squares.
Definition: action.h:117
@ ACTION_SELECT_DEFAULT_AMMO
Change default ammo for current weapon.
Definition: action.h:187
@ ACTION_AUTOPICKUP
Open autopickup manager.
Definition: action.h:283
@ ACTION_SUICIDE
Commit suicide.
Definition: action.h:249
@ NUM_ACTIONS
Not an action, serves as count of enumerated actions.
Definition: action.h:352
@ ACTION_ZOOM_OUT
Zoom view in.
Definition: action.h:309
@ ACTION_SELECT_FIRE_MODE
Change fire mode of the current weapon.
Definition: action.h:185
@ ACTION_UNLOAD
Open the unload item (e.g.
Definition: action.h:175
@ ACTION_RECRAFT
Repeat last craft command.
Definition: action.h:215
@ ACTION_TAKE_OFF
Open the take-off clothing selection menu.
Definition: action.h:157
@ ACTION_TOGGLE_AUTO_FEATURES
Turn auto features on/off.
Definition: action.h:325
@ ACTION_WORLD_MODS
Open active world mods.
Definition: action.h:291
@ ACTION_TOGGLE_DEBUG_MODE
Toggle debug mode.
Definition: action.h:307
@ ACTION_ORGANIZE
Swap inventory letters.
Definition: action.h:149
@ ACTION_MOVE_FORTH_LEFT
Move towards top-left of screen / accelerate and steer left.
Definition: action.h:56
@ ACTION_RELOAD_TILESET
Reload current tileset.
Definition: action.h:323
@ ACTION_CLOSE
Close an item (e.g.
Definition: action.h:106
@ ACTION_EXAMINE
Examine adjacent terrain or furniture.
Definition: action.h:110
@ ACTION_RELOAD_WEAPON
Attempt to reload wielded weapon, then fall back to the load item select menu.
Definition: action.h:171
@ ACTION_RELOAD_ITEM
Open the load item (e.g.
Definition: action.h:169
@ ACTION_PICKUP
Pick up items from one current/adjacent square.
Definition: action.h:115
@ ACTION_LONGCRAFT
Open batch crafting menu.
Definition: action.h:217
@ ACTION_DISTRACTION_MANAGER
Open distraction manager.
Definition: action.h:293
@ ACTION_WEAR
Open the wear clothing selection menu.
Definition: action.h:155
@ ACTION_DIARY
Display Diary window.
Definition: action.h:273
void create_advanced_inv()
auto_notes::auto_note_settings & get_auto_notes_settings()
Definition: auto_note.cpp:606
auto_pickup::player_settings & get_auto_pickup()
Definition: auto_pickup.cpp:52
void display_bodygraph(const Character &u, const bodygraph_id &id)
Definition: bodygraph.cpp:645
void pause()
bool has_active_mutation(const trait_id &b) const
Definition: mutation.cpp:613
pimpl< character_martial_arts > martial_arts_data
Definition: character.h:2724
bool has_active_item(const itype_id &id) const
Whether the player carries an active item of the given item type.
void place_corpse()
outfit worn
Definition: character.h:2690
void long_craft(const std::optional< tripoint > &loc=std::nullopt, const recipe_id &goto_recipe=recipe_id())
Definition: crafting.cpp:421
bool is_blind() const
Returns true if the player isn't able to see.
Definition: character.cpp:5996
item_location ammo_location
Definition: character.h:2764
bool is_mounted() const
Definition: character.cpp:1732
bool is_auto_moving() const
void use_wielded()
Uses the current wielded weapon.
action_id get_next_auto_move_direction()
const pathfinding_settings & get_pathfinding_settings() const override
Returns settings for pathfinding.
item_location get_wielded_item() const
Definition: character.cpp:674
shared_ptr_fast< monster > mounted_creature
Definition: character.h:2800
std::unordered_set< tripoint > get_path_avoid() const override
Returns a set of points we do not want to path through.
void dismount()
Definition: character.cpp:1840
void recraft(const std::optional< tripoint > &loc=std::nullopt)
Definition: crafting.cpp:412
void disp_info(bool customize_character=false)
Handles and displays detailed character info for the '@' screen.
void craft(const std::optional< tripoint > &loc=std::nullopt, const recipe_id &goto_recipe=recipe_id(), const std::string &filterstring="")
Start various types of crafts.
Definition: crafting.cpp:394
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: bionics.cpp:2658
void set_value(const std::string &key, const std::string &value)
Definition: creature.cpp:1949
std::string get_value(const std::string &key) const
Definition: creature.cpp:1959
tripoint_bub_ms pos_bub() const
Definition: creature.cpp:183
void cycle_move_mode()
Definition: avatar.cpp:1365
item::reload_option select_ammo(const item_location &base, bool prompt=false, bool empty=true) override
Select suitable ammo with which to reload the item.
Definition: avatar.cpp:1472
void cycle_move_mode_reverse()
Definition: avatar.cpp:1375
void power_mutations() override
Definition: mutation_ui.cpp:97
void toggle_crouch_mode()
Definition: avatar.cpp:1334
void toggle_run_mode()
Definition: avatar.cpp:1325
void toggle_prone_mode()
Definition: avatar.cpp:1343
void power_bionics() override
Generates and handles the UI for player interaction with installed bionics.
Definition: bionics_ui.cpp:574
void disp_morale()
Provides the window and detailed morale data.
Definition: avatar.cpp:943
void disp_medical()
Opens the medical window.
Definition: medical_ui.cpp:692
void reset_move_mode()
Definition: avatar.cpp:1358
static void show_diary_ui(diary *c_diary)
Definition: diary_ui.cpp:173
void toggle_pixel_minimap() const
Definition: game.cpp:664
int mostseen
Definition: game.h:1152
void display_radiation()
Definition: game.cpp:13024
void list_missions()
Definition: mission_ui.cpp:312
void climb_down(const tripoint &examp)
Climb down from a ledge.
Definition: game.cpp:13536
void pickup_all()
Definition: game.cpp:6332
void wield()
Definition: game.cpp:10212
void set_safe_mode(safe_mode_type mode)
Definition: game.cpp:10367
void reload_wielded(bool prompt=false)
Definition: game.cpp:10029
time_duration turnssincelastmon
Definition: game.h:1144
void zones_manager()
Definition: game.cpp:6942
void display_visibility()
Definition: game.cpp:12938
void display_scent()
Definition: game.cpp:12903
bool save()
Returns false if saving failed.
Definition: game.cpp:3472
void butcher()
Definition: game.cpp:9642
void display_temperature()
Definition: game.cpp:12924
bool auto_travel_mode
Definition: game.h:1138
void zoom_out()
Definition: game.cpp:8147
void toggle_debug_hour_timer()
Definition: game.cpp:12970
void display_transparency()
Definition: game.cpp:13031
void list_items_monsters()
Definition: game.cpp:8347
void chat()
Definition: npctalk.cpp:797
friend timed_event_manager & get_timed_events()
Definition: game.cpp:13861
void quickload()
Definition: game.cpp:13066
void pickup()
Definition: game.cpp:6319
void item_action_menu(item_location loc=item_location())
void vertical_move(int z, bool force, bool peeking=false)
Moves the player vertically.
Definition: game.cpp:11966
void examine(const tripoint &p, bool with_pickup=false)
Definition: game.cpp:6188
void open_consume_item_menu()
std::optional< tripoint > point_selection_menu(const std::vector< tripoint > &pts, bool up=true)
Definition: game.cpp:11913
void insert_item()
Definition: game.cpp:9315
void display_lighting()
Definition: game.cpp:12998
void control_vehicle()
Definition: game.cpp:5842
void drop_in_direction(const tripoint &pnt)
Definition: game.cpp:9336
void peek()
Definition: game.cpp:6352
void reload_weapon(bool try_everything=true)
Definition: game.cpp:10039
bool check_safe_mode_allowed(bool repeat_safe_mode_warnings=true)
Check whether movement is allowed according to safe mode settings.
Definition: game.cpp:10223
void zoom_in()
Definition: game.cpp:8171
void toggle_fullscreen()
Definition: game.cpp:654
void display_vehicle_ai()
Definition: game.cpp:12931
void reload_item()
Definition: game.cpp:10015
void reload_tileset()
Definition: game.cpp:697
void mark_main_ui_adaptor_resize() const
Definition: game.cpp:3806
void unload_container()
Definition: game.cpp:9329
std::vector< tripoint_bub_ms > destination_preview
Definition: game.h:1203
void display_help() const
Definition: help.cpp:139
item_location ammo
Definition: item.h:562
bool is_gun() const
Can this item be used to perform a ranged attack?
Definition: item.cpp:9297
std::string tname(unsigned int quantity=1, tname::segment_bitset const &segments=tname::default_tname) const
Return the (translated) item name.
Definition: item.cpp:6814
gun_mode_id gun_get_mode_id() const
Get id of mode a gun is currently set to, e.g.
Definition: item.cpp:11425
bool has_flag(const flag_id &flag) const
Definition: item.cpp:7578
void gun_cycle_mode()
Switch to the next available firing mode.
Definition: item.cpp:11442
bool is_gunmod() const
Definition: item.cpp:9435
std::map< gun_mode_id, gun_mode > gun_all_modes() const
Get all possible modes for this gun inclusive of any attached gunmods.
Definition: item.cpp:11361
bool gun_set_mode(const gun_mode_id &mode)
Try to set the mode for a gun, returning false if no such mode is possible.
Definition: item.cpp:11433
bool is_outside(const tripoint &p) const
Definition: map.cpp:3395
bool terrain_moppable(const tripoint_bub_ms &p)
Check for moppable fields/items at this location.
Definition: map.cpp:3651
bool mop_spills(const tripoint_bub_ms &p)
Remove moppable fields/items at this location.
Definition: map.cpp:3695
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::unordered_set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
short ignoring
Definition: monster.h:571
T value_as(bool convert=false) const
bool save() const
Definition: options.cpp:4105
cOpt & get_option(const std::string &name)
Definition: options.cpp:4139
std::string show(bool ingame=false, bool world_options_only=false, bool with_tabs=true)
Definition: options.cpp:3390
void sort_armor(Character &guy)
Draws the UI and handles player input for the armor re-ordering window.
void show_adm()
Definition: panels.cpp:642
void add_rule(const std::string &rule_in, Creature::Attitude attitude_in, int proximity_in, rule_state state_in)
void show()
Definition: safemode_ui.cpp:34
bool overmap_visible_weather
Definition: uistate.h:139
bool has_item(const item &it) const
Definition: visitable.cpp:75
#define all_colors
Definition: color.h:13
construction_id construction_menu(const bool blueprint)
coords::coord_point< tripoint, coords::origin::reality_bubble, coords::ms > tripoint_bub_ms
Definition: coordinates.h:716
const flag_id flag_RELOAD_AND_SHOOT("RELOAD_AND_SHOOT")
const flag_id flag_RELOAD_ONE("RELOAD_ONE")
uistatedata uistate
Definition: game.cpp:385
@ SAFE_MODE_OFF
Definition: game.h:62
@ QUIT_SAVED
Definition: game.h:55
static void open_movement_mode_menu()
static void smash()
static void open()
static void takeoff()
static void read()
static void haul_toggle()
static bool has_vehicle_control(avatar &player_character)
static const std::set< action_id > actions_disabled_in_incorporeal
static void wait()
static const efftype_id effect_laserlocked("laserlocked")
static const trait_id trait_SHELL3("SHELL3")
static void rcdrive(const point &d)
static void wear()
static void close()
static const gun_mode_id gun_mode_AUTO("AUTO")
static const bionic_id bio_remote("bio_remote")
static void pldrive(const tripoint &p)
static void haul()
static const trait_id trait_SHELL2("SHELL2")
static const trait_id trait_PROF_CHURL("PROF_CHURL")
static std::map< action_id, std::string > get_actions_disabled_in_shell()
static void cast_spell()
static void loot()
static const flag_id json_flag_MOP("MOP")
static const efftype_id effect_incorporeal("incorporeal")
static void fire()
static const trait_id trait_WAYFARER("WAYFARER")
static void grab()
static void handle_debug_mode()
static void sleep()
static std::map< action_id, std::string > get_actions_disabled_mounted()
static const itype_id itype_radiocontrol("radiocontrol")
help & get_help()
Definition: help.cpp:28
mon_flag_id mon_flag_RIDEABLE_MECH
Definition: mtype.cpp:142
bool isDebugger()
Definition: mapsharing.cpp:82
bool isCompetitive()
Definition: mapsharing.cpp:52
bool eat_here(avatar &you)
void plthrow(avatar &you, item_location loc, const std::optional< tripoint > &blind_throw_from_pos=std::nullopt)
void autoattack(avatar &you, map &m)
void fire_wielded_weapon(avatar &you)
Checks if the wielded weapon is a gun and can be fired then starts interactive aiming.
bool move(avatar &you, map &m, const tripoint &d)
void eat_or_use(avatar &you, item_location loc)
void use_item(avatar &you, item_location &loc, std::string const &method={})
void mend(avatar &you, item_location loc)
void unload(avatar &you)
void debug()
void close_door(map &m, Creature &who, const tripoint_bub_ms &closep)
Handles deducting moves, printing messages (only non-NPCs cause messages), actually closing it,...
Definition: gates.cpp:254
void common(avatar &you)
item_location consume(avatar &you, const item_location &loc=item_location())
Consume an item via a custom menu.
void compare(avatar &you, const std::optional< tripoint > &offset)
void swap_letters(avatar &you)
uint32_t get(const uint32_t &symbol, int n)
void display_visible_weather()
Display overmap like with display() and display the weather that is within line of sight.
void display()
Display overmap centered at the player's position.
options_manager & get_options()
Definition: options.cpp:202
T get_option(const std::string &name, bool convert=false)
Definition: options.h:498
constexpr tripoint tripoint_below
Definition: point.h:272
constexpr tripoint tripoint_above
Definition: point.h:271
static activity_id act
Definition: sounds.cpp:79
void handbrake()

References _, act, ACTION_ACTIONMENU, ACTION_ADVANCEDINV, ACTION_AUTOATTACK, ACTION_AUTONOTES, ACTION_AUTOPICKUP, ACTION_BIONICS, ACTION_BODYSTATUS, ACTION_BUTCHER, ACTION_CAST_SPELL, ACTION_CHAT, ACTION_CLOSE, ACTION_COLOR, ACTION_COMPARE, ACTION_CONSTRUCT, ACTION_CONTROL_VEHICLE, ACTION_CRAFT, ACTION_CYCLE_MOVE, ACTION_CYCLE_MOVE_REVERSE, ACTION_DEBUG, ACTION_DIARY, ACTION_DIR_DROP, ACTION_DISASSEMBLE, ACTION_DISPLAY_LIGHTING, ACTION_DISPLAY_RADIATION, ACTION_DISPLAY_SCENT, ACTION_DISPLAY_SCENT_TYPE, ACTION_DISPLAY_TEMPERATURE, ACTION_DISPLAY_TRANSPARENCY, ACTION_DISPLAY_VEHICLE_AI, ACTION_DISPLAY_VISIBILITY, ACTION_DISTRACTION_MANAGER, ACTION_DROP, ACTION_EAT, ACTION_EXAMINE, ACTION_EXAMINE_AND_PICKUP, ACTION_FACTIONS, ACTION_FIRE, ACTION_FIRE_BURST, ACTION_GRAB, ACTION_HAUL, ACTION_HAUL_TOGGLE, ACTION_HELP, ACTION_IGNORE_ENEMY, ACTION_INSERT_ITEM, ACTION_INVENTORY, ACTION_ITEMACTION, ACTION_KEYBINDINGS, ACTION_LIST_ITEMS, ACTION_LONGCRAFT, ACTION_LOOT, ACTION_MAIN_MENU, ACTION_MAP, ACTION_MEDICAL, ACTION_MEND, ACTION_MESSAGES, ACTION_MISSIONS, ACTION_MORALE, ACTION_MOVE_BACK, ACTION_MOVE_BACK_LEFT, ACTION_MOVE_BACK_RIGHT, ACTION_MOVE_DOWN, ACTION_MOVE_FORTH, ACTION_MOVE_FORTH_LEFT, ACTION_MOVE_FORTH_RIGHT, ACTION_MOVE_LEFT, ACTION_MOVE_RIGHT, ACTION_MOVE_UP, ACTION_MUTATIONS, ACTION_NULL, ACTION_OPEN, ACTION_OPEN_CONSUME, ACTION_OPEN_MOVEMENT, ACTION_OPTIONS, ACTION_ORGANIZE, ACTION_PAUSE, ACTION_PEEK, ACTION_PICK_STYLE, ACTION_PICKUP, ACTION_PICKUP_ALL, ACTION_PL_INFO, ACTION_QUICKLOAD, ACTION_QUICKSAVE, ACTION_READ, ACTION_RECRAFT, ACTION_RELOAD_ITEM, ACTION_RELOAD_TILESET, ACTION_RELOAD_WEAPON, ACTION_RELOAD_WIELDED, ACTION_RESET_MOVE, ACTION_SAFEMODE, ACTION_SAVE, ACTION_SELECT_DEFAULT_AMMO, ACTION_SELECT_FIRE_MODE, ACTION_SKY, ACTION_SLEEP, ACTION_SMASH, ACTION_SORT_ARMOR, ACTION_SUICIDE, ACTION_TAKE_OFF, ACTION_THROW, ACTION_TIMEOUT, ACTION_TOGGLE_AUTO_FEATURES, ACTION_TOGGLE_AUTO_FORAGING, ACTION_TOGGLE_AUTO_MINING, ACTION_TOGGLE_AUTO_PICKUP, ACTION_TOGGLE_AUTO_PULP_BUTCHER, ACTION_TOGGLE_AUTO_TRAVEL_MODE, ACTION_TOGGLE_AUTOSAFE, ACTION_TOGGLE_CROUCH, ACTION_TOGGLE_DEBUG_MODE, ACTION_TOGGLE_FULLSCREEN, ACTION_TOGGLE_HOUR_TIMER, ACTION_TOGGLE_PANEL_ADM, ACTION_TOGGLE_PIXEL_MINIMAP, ACTION_TOGGLE_PREVENT_OCCLUSION, ACTION_TOGGLE_PRONE, ACTION_TOGGLE_RUN, ACTION_TOGGLE_SAFEMODE, ACTION_TOGGLE_THIEF_MODE, ACTION_UNLOAD, ACTION_UNLOAD_CONTAINER, ACTION_USE, ACTION_USE_WIELDED, ACTION_WAIT, ACTION_WEAR, ACTION_WHITELIST_ENEMY, ACTION_WIELD, ACTION_WORKOUT, ACTION_WORLD_MODS, ACTION_ZONES, ACTION_ZOOM_IN, ACTION_ZOOM_OUT, actions_disabled_in_incorporeal, add_msg(), Character::add_msg_if_player(), safemode::add_rule(), all_colors, item::reload_option::ammo, Character::ammo_location, Creature::ANY, Character::assign_activity(), auto_travel_mode, avatar_action::autoattack(), bio_remote, butcher(), cast_spell(), chat(), check_safe_mode_allowed(), choose_adjacent(), Character::clear_destination(), climb_down(), close(), doors::close_door(), game_menus::inv::common(), game_menus::inv::compare(), construction_menu(), game_menus::inv::consume(), control_vehicle(), Character::controlling_vehicle, Character::craft(), create_advanced_inv(), avatar::cycle_move_mode(), avatar::cycle_move_mode_reverse(), debug_menu::debug(), destination_preview, Character::disassemble(), Character::dismount(), Character::disp_info(), avatar::disp_medical(), avatar::disp_morale(), ui::omap::display(), display_bodygraph(), help::display_help(), display_lighting(), Messages::display_messages(), display_radiation(), display_scent(), display_temperature(), display_transparency(), display_vehicle_ai(), display_visibility(), ui::omap::display_visible_weather(), drop_in_direction(), avatar_action::eat_here(), avatar_action::eat_or_use(), effect_incorporeal, effect_laserlocked, examine(), faction_manager_ptr, fire(), avatar_action::fire_wielded_weapon(), flag_RELOAD_AND_SHOOT, flag_RELOAD_ONE, rotatable_symbols::get(), get_actions_disabled_in_shell(), get_actions_disabled_mounted(), get_auto_notes_settings(), get_auto_pickup(), avatar::get_avatar_diary(), get_delta_from_movement_action(), get_distraction_manager(), get_help(), panel_manager::get_manager(), get_map, avatar::get_mon_visible(), Character::get_next_auto_move_direction(), options_manager::get_option(), get_option(), get_options(), Character::get_path_avoid(), Character::get_pathfinding_settings(), get_player_character, get_safemode(), get_timed_events, Creature::get_value(), Character::get_wielded_item(), grab(), item::gun_all_modes(), item::gun_cycle_mode(), item::gun_get_mode_id(), gun_mode_AUTO, item::gun_set_mode(), handbrake(), handle_debug_mode(), Character::has_active_bionic(), Character::has_active_item(), Character::has_active_mutation(), Creature::has_effect(), item::has_flag(), map::has_flag(), visitable::has_item(), Character::has_trait(), has_vehicle_control(), haul(), haul_toggle(), monster::ignoring, Character::in_vehicle, insert_item(), Character::is_auto_moving(), Character::is_blind(), item::is_gun(), item::is_gunmod(), Character::is_mounted(), map::is_outside(), MAP_SHARING::isCompetitive(), MAP_SHARING::isDebugger(), item_action_menu(), itype_radiocontrol, json_flag_MOP, list_items_monsters(), list_missions(), Character::long_craft(), loot(), m, m_info, m_warning, mark_main_ui_adaptor_resize(), Character::martial_arts_data, avatar_action::mend(), Creature::mod_moves(), mon_flag_RIDEABLE_MECH, map::mop_spills(), mostseen, Character::mounted_creature, avatar_action::move(), monster_visible_info::new_seen_mon, no, NUM_ACTIONS, one_in(), open(), open_consume_item_menu(), open_movement_mode_menu(), uistatedata::overmap_visible_weather, OVERRIDE_PLACE, Character::pause(), peek(), pickup(), pickup_all(), Character::place_corpse(), pldrive(), avatar_action::plthrow(), point_selection_menu(), point_zero, map::points_in_radius(), Creature::pos(), Creature::pos_bub(), avatar::power_bionics(), avatar::power_mutations(), query_yn(), quickload(), quicksave(), QUIT_SAVED, QUIT_SUICIDE, rcdrive(), read(), Character::recraft(), reload_item(), reload_tileset(), reload_weapon(), reload_wielded(), Creature::remove_effect(), avatar::reset_move_mode(), rl_dist(), map::route(), safe_mode, SAFE_MODE_OFF, SAFE_MODE_ON, SAFE_MODE_STOP, safe_mode_warning_logged, save(), options_manager::save(), SEEX, avatar::select_ammo(), Character::set_destination(), Creature::set_moves(), set_safe_mode(), Creature::set_value(), options_manager::cOpt::setNext(), auto_pickup::player_settings::show(), distraction_manager::distraction_manager_gui::show(), safemode::show(), options_manager::show(), panel_manager::show_adm(), diary::show_diary_ui(), auto_notes::auto_note_settings::show_gui(), sleep(), smash(), outfit::sort_armor(), game_menus::inv::swap_letters(), takeoff(), map::terrain_moppable(), TFLAG_GOES_DOWN, TFLAG_NO_FLOOR, item::tname(), avatar::toggle_crouch_mode(), toggle_debug_hour_timer(), toggle_fullscreen(), toggle_pixel_minimap(), avatar::toggle_prone_mode(), avatar::toggle_run_mode(), trait_PROF_CHURL, trait_SHELL2, trait_SHELL3, trait_WAYFARER, tripoint_above, tripoint_below, turnssincelastmon, u, uistate, avatar_action::unload(), unload_container(), uquit, avatar_action::use_item(), Character::use_wielded(), options_manager::cOpt::value_as(), map::veh_at(), vertical_move(), wait(), wear(), WHITELISTED, wield(), world_generator, Character::worn, yes, zones_manager(), zoom_in(), and zoom_out().

Referenced by handle_action().

◆ draw()

void game::draw ( ui_adaptor ui)

Definition at line 3969 of file game.cpp.

3970 {
3971  if( test_mode ) {
3972  return;
3973  }
3974 
3975  ter_view_p.z = ( u.pos() + u.view_offset ).z;
3978 
3979  werase( w_terrain );
3981  draw_ter();
3982  for( auto it = draw_callbacks.begin(); it != draw_callbacks.end(); ) {
3983  shared_ptr_fast<draw_callback_t> cb = it->lock();
3984  if( cb ) {
3985  ( *cb )();
3986  ++it;
3987  } else {
3988  it = draw_callbacks.erase( it );
3989  }
3990  }
3992  // Only draw blinking symbols when in active phase
3993  if( blink_active_phase ) {
3995  }
3997 
3998  draw_panels( true );
3999 
4000  // Ensure that the cursor lands on the character when everything is drawn.
4001  // This allows screen readers to describe the area around the player, making it
4002  // much easier to play with them
4003  // (e.g. for blind players)
4004  ui.set_cursor( w_terrain, -u.view_offset.xy() + point( POSX, POSY ) );
4005 }
bool test_mode
tripoint ter_view_p
Definition: game.h:1107
bool blink_active_phase
Definition: game.h:265
void draw_panels(bool force_draw=false)
Definition: game.cpp:4007
void draw_async_anim_curses()
Definition: game.cpp:3919
void void_blink_curses()
Definition: game.cpp:3959
void draw_blink_curses()
Definition: game.cpp:3945
void draw_ter(bool draw_sounds=true)
Definition: game.cpp:4130
void update_visibility_cache(int zlev)
Definition: map.cpp:6811
void build_map_cache(int zlev, bool skip_lightmap=false)
Definition: map.cpp:9542

References blink_active_phase, map::build_map_cache(), draw_async_anim_curses(), draw_blink_curses(), draw_callbacks, draw_panels(), draw_ter(), m, Creature::pos(), POSX, POSY, ter_view_p, test_mode, u, map::update_visibility_cache(), Character::view_offset, void_blink_curses(), w_terrain, catacurses::werase(), catacurses::wnoutrefresh(), tripoint::xy(), and tripoint::z.

◆ draw_async_anim()

void game::draw_async_anim ( const tripoint p,
const std::string &  tile_id,
const std::string &  ncstr = "",
const nc_color nccol = c_black 
)

Definition at line 893 of file animation.cpp.

895 {
896  if( !ncstr.empty() ) {
897  g->init_draw_async_anim_curses( p, ncstr, nccol );
898  }
899 }

References g.

Referenced by walk_move().

◆ draw_async_anim_curses()

void game::draw_async_anim_curses ( )

Definition at line 3919 of file game.cpp.

3920 {
3921  // game::draw_async_anim_curses can be called multiple times, storing each animation to be played in async_anim_layer_curses
3922  // Iterate through every animation in async_anim_layer
3923  for( const auto &anim : async_anim_layer_curses ) {
3924  const tripoint p = anim.first - u.view_offset + tripoint( POSX - u.posx(), POSY - u.posy(),
3925  -u.posz() );
3926  const std::string ncstr = anim.second.first;
3927  const nc_color nccol = anim.second.second;
3928 
3929  mvwprintz( w_terrain, p.xy(), nccol, ncstr );
3930  }
3931 }
int posy() const
Definition: creature.h:314
int posx() const
Definition: creature.h:311
std::map< tripoint, std::pair< std::string, nc_color > > async_anim_layer_curses
Definition: game.h:257

References async_anim_layer_curses, mvwprintz(), Creature::posx(), POSX, Creature::posy(), POSY, Creature::posz(), tripoint, u, Character::view_offset, w_terrain, and tripoint::xy().

Referenced by draw().

◆ draw_below_override()

void game::draw_below_override ( const tripoint p,
bool  draw 
)

Definition at line 1019 of file animation.cpp.

1020 {
1021 }

◆ draw_blink_curses()

void game::draw_blink_curses ( )

Definition at line 3945 of file game.cpp.

3946 {
3947  // game::draw_blink_curses can be called multiple times, storing each animation to be played in blink_layer_curses
3948  // Iterate through every animation in async_anim_layer
3949  for( const auto &anim : blink_layer_curses ) {
3950  const tripoint p = anim.first - u.view_offset + tripoint( POSX - u.posx(), POSY - u.posy(),
3951  -u.posz() );
3952  const std::string ncstr = anim.second.first;
3953  const nc_color nccol = anim.second.second;
3954 
3955  mvwprintz( w_terrain, p.xy(), nccol, ncstr );
3956  }
3957 }
std::map< tripoint, std::pair< std::string, nc_color > > blink_layer_curses
Definition: game.h:268

References blink_layer_curses, mvwprintz(), Creature::posx(), POSX, Creature::posy(), POSY, Creature::posz(), tripoint, u, Character::view_offset, w_terrain, and tripoint::xy().

Referenced by draw().

◆ draw_bullet()

void game::draw_bullet ( const tripoint t,
int  i,
const std::vector< tripoint > &  trajectory,
char  bullet 
)

Definition at line 520 of file animation.cpp.

522 {
523  draw_bullet_curses( m, t, bullet, &trajectory[i] );
524 }
void draw_bullet_curses(map &m, const tripoint &t, const char bullet, const tripoint *const p)
Definition: animation.cpp:456
std::vector< tripoint > trajectory
Definition: ranged.h:29

References anonymous_namespace{animation.cpp}::draw_bullet_curses(), and m.

◆ draw_critter()

void game::draw_critter ( const Creature critter,
const tripoint center 
)

Definition at line 4087 of file game.cpp.

4088 {
4089  const int my = POSY + ( critter.posy() - center.y );
4090  const int mx = POSX + ( critter.posx() - center.x );
4091  if( !is_valid_in_w_terrain( point( mx, my ) ) ) {
4092  return;
4093  }
4094  if( critter.posz() != center.z ) {
4095  static constexpr tripoint up_tripoint( tripoint_above );
4096  if( critter.posz() == center.z - 1 &&
4097  ( debug_mode || u.sees( critter ) ) &&
4098  m.valid_move( critter.pos(), critter.pos() + up_tripoint, false, true ) ) {
4099  // Monster is below
4100  // TODO: Make this show something more informative than just green 'v'
4101  // TODO: Allow looking at this mon with look command
4102  init_draw_blink_curses( tripoint( critter.pos().xy(), center.z ), "v", c_green_cyan );
4103  }
4104  if( critter.posz() == center.z + 1 &&
4105  ( debug_mode || u.sees( critter ) ) &&
4106  m.valid_move( critter.pos(), critter.pos() + tripoint_below, false, true ) ) {
4107  // Monster is above
4108  init_draw_blink_curses( tripoint( critter.pos().xy(), center.z ), "^", c_green_cyan );
4109  }
4110  return;
4111  }
4112  if( u.sees( critter ) || &critter == &u ) {
4113  critter.draw( w_terrain, center.xy(), false );
4114  return;
4115  }
4116 
4117  if( u.sees_with_infrared( critter ) || u.sees_with_specials( critter ) ) {
4118  mvwputch( w_terrain, point( mx, my ), c_red, '?' );
4119  }
4120 }
bool sees_with_specials(const Creature &critter) const
Definition: character.cpp:6064
bool sees_with_infrared(const Creature &critter) const
Check whether the this player can see the other creature with infrared.
void draw(const catacurses::window &w, const point &origin, bool inverted) const
Definition: creature.cpp:2977
void init_draw_blink_curses(const tripoint &p, const std::string &ncstr, const nc_color &nccol)
Definition: game.cpp:3938
#define c_green_cyan
Definition: color.h:158
bool debug_mode
Extended debugging mode, can be toggled during game.
Definition: debug.cpp:210
bool is_valid_in_w_terrain(const point &p)
Definition: game.cpp:387

References c_green_cyan, c_red, center, debug_mode, Creature::draw(), init_draw_blink_curses(), is_valid_in_w_terrain(), m, mvwputch(), point, Creature::pos(), Creature::posx(), POSX, Creature::posy(), POSY, Creature::posz(), Character::sees(), Character::sees_with_infrared(), Character::sees_with_specials(), tripoint, tripoint_above, tripoint_below, u, map::valid_move(), w_terrain, and tripoint::xy().

Referenced by draw_ter().

◆ draw_cursor()

void game::draw_cursor ( const tripoint p) const

Definition at line 742 of file animation.cpp.

743 {
744  const tripoint rp = relative_view_pos( *this, p );
745  mvwputch_inv( w_terrain, rp.xy(), c_light_green, 'X' );
746 }
#define c_light_green
Definition: color.h:26
tripoint relative_view_pos(const game &g, const tripoint &p) noexcept
Definition: animation.cpp:128
void mvwputch_inv(const catacurses::window &w, const point &p, nc_color FG, int ch)
Definition: output.cpp:604

References c_light_green, mvwputch_inv(), anonymous_namespace{animation.cpp}::relative_view_pos(), w_terrain, and tripoint::xy().

Referenced by draw_look_around_cursor().

◆ draw_field_override()

void game::draw_field_override ( const tripoint p,
const field_type_id id 
)

Definition at line 975 of file animation.cpp.

976 {
977 }

◆ draw_furniture_override()

void game::draw_furniture_override ( const tripoint p,
const furn_id id 
)

Definition at line 936 of file animation.cpp.

937 {
938 }

◆ draw_graffiti_override()

void game::draw_graffiti_override ( const tripoint p,
bool  has 
)

Definition at line 949 of file animation.cpp.

950 {
951 }

◆ draw_highlight()

void game::draw_highlight ( const tripoint p)

Definition at line 755 of file animation.cpp.

756 {
757  // Do nothing
758 }

◆ draw_hit_mon()

void game::draw_hit_mon ( const tripoint p,
const monster m,
bool  dead = false 
)

Definition at line 583 of file animation.cpp.

584 {
585  draw_hit_mon_curses( p, m, u, dead );
586 }
void draw_hit_mon_curses(const tripoint &center, const monster &m, const avatar &u, const bool dead)
Definition: animation.cpp:554

References anonymous_namespace{animation.cpp}::draw_hit_mon_curses(), m, and u.

◆ draw_hit_player()

void game::draw_hit_player ( const Character p,
int  dam 
)

Definition at line 628 of file animation.cpp.

629 {
630  draw_hit_player_curses( *this, p, dam );
631 }
void draw_hit_player_curses(const game &, const Character &p, const int dam)
Definition: animation.cpp:591

References anonymous_namespace{animation.cpp}::draw_hit_player_curses().

◆ draw_item_override()

void game::draw_item_override ( const tripoint p,
const itype_id id,
const mtype_id mid,
bool  hilite 
)

Definition at line 989 of file animation.cpp.

991 {
992 }

◆ draw_line() [1/3]

void game::draw_line ( const tripoint p,
const std::vector< tripoint > &  points 
)

Definition at line 728 of file animation.cpp.

729 {
730  draw_line_curses( *this, points );
731 }
void draw_line_curses(game &g, const std::vector< tripoint > &points)
Definition: animation.cpp:707

References anonymous_namespace{animation.cpp}::draw_line_curses().

◆ draw_line() [2/3]

void game::draw_line ( const tripoint p,
const tripoint center_point,
const std::vector< tripoint > &  points,
bool  noreveal = false 
)

Definition at line 683 of file animation.cpp.

685 {
686  if( !u.sees( p ) ) {
687  return;
688  }
689 
690  draw_line_curses( *this, center, points, noreveal );
691 }

References center, anonymous_namespace{animation.cpp}::draw_line_curses(), Character::sees(), and u.

Referenced by draw_line(), and draw_ter().

◆ draw_line() [3/3]

void game::draw_line ( const tripoint_bub_ms p,
const tripoint_bub_ms center_point,
const std::vector< tripoint_bub_ms > &  points,
bool  noreveal = false 
)

Definition at line 694 of file animation.cpp.

696 {
697  std::vector<tripoint> raw_points;
698  std::transform( points.begin(), points.end(), std::back_inserter( raw_points ),
699  []( const tripoint_bub_ms & t ) {
700  return t.raw();
701  } );
702  draw_line( p.raw(), center.raw(), raw_points, noreveal );
703 }
constexpr const Point & raw() const
Definition: coordinates.h:157
void draw_line(const tripoint &p, const tripoint &center_point, const std::vector< tripoint > &points, bool noreveal=false)
Definition: animation.cpp:683

References center, draw_line(), and coords::coord_point_mut< Point, Subpoint, InBounds >::raw().

◆ draw_look_around_cursor()

void game::draw_look_around_cursor ( const tripoint lp,
const visibility_variables cache 
)

Definition at line 6418 of file game.cpp.

6419 {
6420  if( !liveview.is_enabled() ) {
6421 #if defined( TILES )
6422  if( is_draw_tiles_mode() ) {
6423  draw_cursor( lp );
6424  return;
6425  }
6426 #endif
6427  const tripoint view_center = u.pos() + u.view_offset;
6429  const bool inbounds = m.inbounds( lp );
6430  if( inbounds ) {
6431  visibility = m.get_visibility( m.apparent_light_at( lp, cache ), cache );
6432  }
6433  if( visibility == visibility_type::CLEAR ) {
6434  const Creature *const creature = get_creature_tracker().creature_at( lp, true );
6435  if( creature != nullptr && u.sees( *creature ) ) {
6436  creature->draw( w_terrain, view_center, true );
6437  } else {
6438  m.drawsq( w_terrain, lp, drawsq_params().highlight( true ).center( view_center ) );
6439  }
6440  } else {
6441  std::string visibility_indicator;
6442  nc_color visibility_indicator_color = c_white;
6443  switch( visibility ) {
6445  // Already handled by the outer if statement
6446  break;
6449  visibility_indicator = '#';
6450  visibility_indicator_color = c_pink;
6451  break;
6452  case visibility_type::DARK:
6453  visibility_indicator = '#';
6454  visibility_indicator_color = c_dark_gray;
6455  break;
6456  case visibility_type::LIT:
6457  visibility_indicator = '#';
6458  visibility_indicator_color = c_light_gray;
6459  break;
6461  visibility_indicator = 'x';
6462  visibility_indicator_color = c_white;
6463  break;
6464  }
6465 
6466  const tripoint screen_pos = point( POSX, POSY ) + lp - view_center;
6467  mvwputch( w_terrain, screen_pos.xy(), visibility_indicator_color, visibility_indicator );
6468  }
6469  }
6470 }
void draw_cursor(const tripoint &p) const
Definition: animation.cpp:742
bool is_enabled()
Definition: live_view.cpp:77
bool inbounds(const tripoint &p) const
Definition: map.cpp:9057
visibility_type get_visibility(lit_level ll, const visibility_variables &cache) const
Definition: map.cpp:6884
lit_level apparent_light_at(const tripoint &p, const visibility_variables &cache) const
Determine the visible light level for a tile, based on light_at for the tile, vision distance,...
Definition: lightmap.cpp:742
void drawsq(const catacurses::window &w, const tripoint &p, const drawsq_params &params) const
Draw the map tile at the given coordinate.
Definition: map.cpp:7059
#define c_dark_gray
Definition: color.h:18
#define c_pink
Definition: color.h:29
visibility_type
Definition: enums.h:115
bool is_draw_tiles_mode()
Check whether we're in tile drawing mode.
Definition: output.cpp:3284
Draw parameters used by map::drawsq() and similar methods.
Definition: map.h:168

References map::apparent_light_at(), BOOMER, BOOMER_DARK, c_dark_gray, c_light_gray, c_pink, c_white, center, CLEAR, creature, creature_tracker::creature_at(), DARK, draw_cursor(), map::drawsq(), get_creature_tracker, map::get_visibility(), HIDDEN, map::inbounds(), is_draw_tiles_mode(), live_view::is_enabled(), LIT, liveview, m, mvwputch(), point, Creature::pos(), POSX, POSY, Character::sees(), u, Character::view_offset, w_terrain, and tripoint::xy().

Referenced by look_around().

◆ draw_minimap()

void game::draw_minimap ( )
private

Definition at line 4190 of file game.cpp.

4191 {
4192 
4193  // Draw the box
4194  werase( w_minimap );
4196 
4197  const tripoint_abs_omt curs = u.global_omt_location();
4198  const point_abs_omt curs2( curs.xy() );
4200  bool drew_mission = targ == overmap::invalid_tripoint;
4201 
4202  const int levz = m.get_abs_sub().z();
4203  for( int i = -2; i <= 2; i++ ) {
4204  for( int j = -2; j <= 2; j++ ) {
4205  const point_abs_omt om( curs2 + point( i, j ) );
4206  nc_color ter_color;
4207  tripoint_abs_omt omp( om, levz );
4208  std::string ter_sym;
4209  const bool seen = overmap_buffer.seen( omp );
4210  if( overmap_buffer.has_note( omp ) ) {
4211 
4212  const std::string &note_text = overmap_buffer.note( omp );
4213 
4214  ter_color = c_yellow;
4215  ter_sym = "N";
4216 
4217  int symbolIndex = note_text.find( ':' );
4218  int colorIndex = note_text.find( ';' );
4219 
4220  bool symbolFirst = symbolIndex < colorIndex;
4221 
4222  if( colorIndex > -1 && symbolIndex > -1 ) {
4223  if( symbolFirst ) {
4224  if( colorIndex > 4 ) {
4225  colorIndex = -1;
4226  }
4227  if( symbolIndex > 1 ) {
4228  symbolIndex = -1;
4229  colorIndex = -1;
4230  }
4231  } else {
4232  if( symbolIndex > 4 ) {
4233  symbolIndex = -1;
4234  }
4235  if( colorIndex > 2 ) {
4236  colorIndex = -1;
4237  }
4238  }
4239  } else if( colorIndex > 2 ) {
4240  colorIndex = -1;
4241  } else if( symbolIndex > 1 ) {
4242  symbolIndex = -1;
4243  }
4244 
4245  if( symbolIndex > -1 ) {
4246  int symbolStart = 0;
4247  if( colorIndex > -1 && !symbolFirst ) {
4248  symbolStart = colorIndex + 1;
4249  }
4250  ter_sym = note_text.substr( symbolStart, symbolIndex - symbolStart ).c_str()[0];
4251  }
4252 
4253  if( colorIndex > -1 ) {
4254 
4255  int colorStart = 0;
4256 
4257  if( symbolIndex > -1 && symbolFirst ) {
4258  colorStart = symbolIndex + 1;
4259  }
4260 
4261  std::string sym = note_text.substr( colorStart, colorIndex - colorStart );
4262 
4263  if( sym.length() == 2 ) {
4264  if( sym == "br" ) {
4265  ter_color = c_brown;
4266  } else if( sym == "lg" ) {
4267  ter_color = c_light_gray;
4268  } else if( sym == "dg" ) {
4269  ter_color = c_dark_gray;
4270  }
4271  } else {
4272  char colorID = sym.c_str()[0];
4273  if( colorID == 'r' ) {
4274  ter_color = c_light_red;
4275  } else if( colorID == 'R' ) {
4276  ter_color = c_red;
4277  } else if( colorID == 'g' ) {
4278  ter_color = c_light_green;
4279  } else if( colorID == 'G' ) {
4280  ter_color = c_green;
4281  } else if( colorID == 'b' ) {
4282  ter_color = c_light_blue;
4283  } else if( colorID == 'B' ) {
4284  ter_color = c_blue;
4285  } else if( colorID == 'W' ) {
4286  ter_color = c_white;
4287  } else if( colorID == 'C' ) {
4288  ter_color = c_cyan;
4289  } else if( colorID == 'c' ) {
4290  ter_color = c_light_cyan;
4291  } else if( colorID == 'P' ) {
4292  ter_color = c_pink;
4293  } else if( colorID == 'm' ) {
4294  ter_color = c_magenta;
4295  }
4296  }
4297  }
4298  } else if( !seen ) {
4299  ter_sym = " ";
4300  ter_color = c_black;
4301  } else if( overmap_buffer.has_vehicle( omp ) ) {
4302  ter_color = c_cyan;
4303  ter_sym = overmap_buffer.get_vehicle_ter_sym( omp );
4304  } else {
4305  const oter_id &cur_ter = overmap_buffer.ter( omp );
4306  ter_sym = cur_ter->get_symbol();
4307  if( overmap_buffer.is_explored( omp ) ) {
4308  ter_color = c_dark_gray;
4309  } else {
4310  ter_color = cur_ter->get_color();
4311  }
4312  }
4313  if( !drew_mission && targ.xy() == omp.xy() ) {
4314  // If there is a mission target, and it's not on the same
4315  // overmap terrain as the player character, mark it.
4316  // TODO: Inform player if the mission is above or below
4317  drew_mission = true;
4318  if( i != 0 || j != 0 ) {
4319  ter_color = red_background( ter_color );
4320  }
4321  }
4322  if( i == 0 && j == 0 ) {
4323  mvwputch_hi( w_minimap, point( 3, 3 ), ter_color, ter_sym );
4324  } else {
4325  mvwputch( w_minimap, point( 3 + i, 3 + j ), ter_color, ter_sym );
4326  }
4327  }
4328  }
4329 
4330  // Print arrow to mission if we have one!
4331  if( !drew_mission ) {
4332  double slope = curs2.x() != targ.x() ?
4333  static_cast<double>( targ.y() - curs2.y() ) / ( targ.x() - curs2.x() ) : 4;
4334 
4335  if( curs2.x() == targ.x() || std::fabs( slope ) > 3.5 ) { // Vertical slope
4336  if( targ.y() > curs2.y() ) {
4337  mvwputch( w_minimap, point( 3, 6 ), c_red, "*" );
4338  } else {
4339  mvwputch( w_minimap, point( 3, 0 ), c_red, "*" );
4340  }
4341  } else {
4343  if( std::fabs( slope ) >= 1. ) { // y diff is bigger!
4344  arrow.y = targ.y() > curs2.y() ? 6 : 0;
4345  arrow.x =
4346  static_cast<int>( 3 + 3 * ( targ.y() > curs2.y() ? slope : ( 0 - slope ) ) );
4347  if( arrow.x < 0 ) {
4348  arrow.x = 0;
4349  }
4350  if( arrow.x > 6 ) {
4351  arrow.x = 6;
4352  }
4353  } else {
4354  arrow.x = targ.x() > curs2.x() ? 6 : 0;
4355  arrow.y = static_cast<int>( 3 + 3 * ( targ.x() > curs2.x() ? slope : -slope ) );
4356  if( arrow.y < 0 ) {
4357  arrow.y = 0;
4358  }
4359  if( arrow.y > 6 ) {
4360  arrow.y = 6;
4361  }
4362  }
4363  char glyph = '*';
4364  if( targ.z() > u.posz() ) {
4365  glyph = '^';
4366  } else if( targ.z() < u.posz() ) {
4367  glyph = 'v';
4368  }
4369 
4370  mvwputch( w_minimap, arrow, c_red, glyph );
4371  }
4372  }
4373 
4374  Character &player_character = get_player_character();
4375  const int sight_points = player_character.overmap_sight_range( g->light_level(
4376  player_character.posz() ) );
4377  for( int i = -3; i <= 3; i++ ) {
4378  for( int j = -3; j <= 3; j++ ) {
4379  if( i > -3 && i < 3 && j > -3 && j < 3 ) {
4380  continue; // only do hordes on the border, skip inner map
4381  }
4382  const tripoint_abs_omt omp( curs2 + point( i, j ), levz );
4384  if( overmap_buffer.seen( omp )
4385  && player_character.overmap_los( omp, sight_points ) ) {
4386  mvwputch( w_minimap, point( i + 3, j + 3 ), c_green,
4387  overmap_buffer.get_horde_size( omp ) > HORDE_VISIBILITY_SIZE * 2 ? 'Z' : 'z' );
4388  }
4389  }
4390  }
4391  }
4392 
4394 }
bool overmap_los(const tripoint_abs_omt &omt, int sight_points) const
Returns true if overmap tile is within player line-of-sight.
Definition: character.cpp:1266
int overmap_sight_range(float light_level) const
Returns the distance the player can see on the overmap.
Definition: character.cpp:1288
tripoint_abs_omt get_active_mission_target() const
Returns the target of the active mission or overmap::invalid_tripoint if there is no active mission.
Definition: avatar.cpp:339
constexpr auto y() const
Definition: coordinates.h:164
constexpr auto x() const
Definition: coordinates.h:161
constexpr auto z() const
Definition: coordinates.h:167
constexpr auto xy() const
Definition: coordinates.h:273
tripoint_abs_sm get_abs_sub() const
return abs_sub
Definition: map.cpp:9663
static constexpr tripoint_abs_omt invalid_tripoint
Dummy value, used to indicate that a point returned by a function is invalid.
Definition: overmap.h:277
bool seen(const tripoint_abs_omt &p)
const std::string & note(const tripoint_abs_omt &p)
int get_horde_size(const tripoint_abs_omt &p)
bool is_explored(const tripoint_abs_omt &p)
std::string get_vehicle_ter_sym(const tripoint_abs_omt &omt)
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
bool has_note(const tripoint_abs_omt &p)
Uses global overmap terrain coordinates.
bool has_vehicle(const tripoint_abs_omt &p)
nc_color red_background(const nc_color &c)
Definition: color.cpp:552
#define c_blue
Definition: color.h:21
#define c_black
Definition: color.h:15
#define c_yellow
Definition: color.h:30
#define c_light_cyan
Definition: color.h:28
#define c_cyan
Definition: color.h:22
#define c_light_red
Definition: color.h:25
constexpr int HORDE_VISIBILITY_SIZE
constexpr scale om
Definition: coordinates.h:42
void mvwputch_hi(const catacurses::window &w, const point &p, nc_color FG, int ch)
Definition: output.cpp:621
std::string get_symbol(const bool from_land_use_code=false) const
Definition: omdata.h:334
nc_color get_color(const bool from_land_use_code=false) const
Definition: omdata.h:342

References arrow, c_black, c_blue, c_brown, c_cyan, c_dark_gray, c_green, c_light_blue, c_light_cyan, c_light_gray, c_light_green, c_light_red, c_magenta, c_pink, c_red, c_white, c_yellow, draw_border(), units::fabs(), g, map::get_abs_sub(), avatar::get_active_mission_target(), oter_t::get_color(), overmapbuffer::get_horde_size(), get_player_character, oter_t::get_symbol(), overmapbuffer::get_vehicle_ter_sym(), Creature::global_omt_location(), overmapbuffer::has_note(), overmapbuffer::has_vehicle(), HORDE_VISIBILITY_SIZE, overmap::invalid_tripoint, overmapbuffer::is_explored(), m, mvwputch(), mvwputch_hi(), overmapbuffer::note(), coords::om, overmap_buffer, Character::overmap_los(), Character::overmap_sight_range(), point, point_north_west, Creature::posz(), red_background(), overmapbuffer::seen(), overmapbuffer::ter(), u, w_minimap, catacurses::werase(), catacurses::wnoutrefresh(), coords::coord_point_mut< Point, Subpoint, InBounds >::x(), coords::coord_point< Point, Origin, Scale, InBounds >::xy(), coords::coord_point_mut< Point, Subpoint, InBounds >::y(), and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

◆ draw_monster_override()

void game::draw_monster_override ( const tripoint p,
const mtype_id id,
int  count,
bool  more,
Creature::Attitude  att 
)

Definition at line 1033 of file animation.cpp.

1035 {
1036 }

◆ draw_panels()

void game::draw_panels ( bool  force_draw = false)

Definition at line 4007 of file game.cpp.

4008 {
4009  static int previous_turn = -1;
4010  const int current_turn = to_turns<int>( calendar::turn - calendar::turn_zero );
4011  const bool draw_this_turn = current_turn > previous_turn || force_draw;
4013  int y = 0;
4014  const bool sidebar_right = get_option<std::string>( "SIDEBAR_POSITION" ) == "right";
4015  int spacer = get_option<bool>( "SIDEBAR_SPACERS" ) ? 1 : 0;
4016  // Total up height used by all panels, and see what is left over for log
4017  int log_height = 0;
4018  for( const window_panel &panel : mgr.get_current_layout().panels() ) {
4019  // Skip height processing
4020  if( !panel.toggle || !panel.render() ) {
4021  continue;
4022  }
4023  // The panel with height -2 is the message log panel
4024  const int p_height = panel.get_height();
4025  if( p_height != -2 ) {
4026  log_height += p_height + spacer;
4027  }
4028  }
4029  log_height = std::max( TERMY - log_height, 3 );
4030  // Draw each panel having render() true
4031  for( const window_panel &panel : mgr.get_current_layout().panels() ) {
4032  if( panel.render() ) {
4033  // height clamped to window height.
4034  int h = std::min( panel.get_height(), TERMY - y );
4035  // The panel with height -2 is the message log panel
4036  if( h == -2 ) {
4037  h = log_height;
4038  }
4039  h += spacer;
4040  if( panel.toggle && panel.render() && h > 0 ) {
4041  if( panel.always_draw || draw_this_turn ) {
4042  catacurses::window w = catacurses::newwin( h, panel.get_width(),
4043  point( sidebar_right ? TERMX - panel.get_width() : 0, y ) );
4044  int tmp_h = panel.draw( { u, w, panel.get_widget() } );
4045  h += tmp_h;
4046  // lines skipped for rendering -> reclaim space in the sidebar
4047  if( tmp_h < 0 ) {
4048  y += h;
4049  log_height -= tmp_h;
4050  continue;
4051  }
4052  }
4053  if( show_panel_adm ) {
4054  const std::string panel_name = panel.get_name();
4055  const int panel_name_width = utf8_width( panel_name );
4056  catacurses::window label = catacurses::newwin( 1, panel_name_width, point( sidebar_right ?
4057  TERMX - panel.get_width() - panel_name_width - 1 : panel.get_width() + 1, y ) );
4058  werase( label );
4059  mvwprintz( label, point_zero, c_light_red, panel_name );
4060  wnoutrefresh( label );
4061  label = catacurses::newwin( h, 1,
4062  point( sidebar_right ? TERMX - panel.get_width() - 1 : panel.get_width(), y ) );
4063  werase( label );
4064  if( h == 1 ) {
4066  } else {
4068  for( int i = 1; i < h - 1; i++ ) {
4069  mvwputch( label, point( 0, i ), c_light_red, LINE_XOXO );
4070  }
4071  mvwputch( label, point( 0, h - 1 ), c_light_red, sidebar_right ? LINE_XXOO : LINE_XOOX );
4072  }
4073  wnoutrefresh( label );
4074  }
4075  y += h;
4076  }
4077  }
4078  }
4079  previous_turn = current_turn;
4080 }
bool show_panel_adm
Definition: game.h:1135
const std::vector< window_panel > & panels() const
Definition: panels.cpp:153
panel_layout & get_current_layout()
Definition: panels.cpp:355
constexpr time_point turn_zero
Represents time point 0.
Definition: calendar.h:541
#define LINE_XOXO
Definition: output.h:46
#define LINE_OXOX
Definition: output.h:47
#define LINE_OXXX
Definition: output.h:55
#define LINE_XOOX
Definition: output.h:51
#define LINE_XXOO
Definition: output.h:48
Struct used for storing labels (easier to json opposed to a std::map<point, std::string>)
Definition: vehicle.h:687

References c_light_red, panel_manager::get_current_layout(), panel_manager::get_manager(), LINE_OXOX, LINE_OXXX, LINE_XOOX, LINE_XOXO, LINE_XXOO, max(), min(), mvwprintz(), mvwputch(), catacurses::newwin(), panel_layout::panels(), point, point_zero, show_panel_adm, TERMX, TERMY, calendar::turn, calendar::turn_zero, u, utf8_width(), catacurses::werase(), and catacurses::wnoutrefresh().

Referenced by draw().

◆ draw_pixel_minimap()

void game::draw_pixel_minimap ( const catacurses::window w)

Definition at line 4082 of file game.cpp.

4083 {
4084  w_pixel_minimap = w;
4085 }

References w_pixel_minimap.

◆ draw_radiation_override()

void game::draw_radiation_override ( const tripoint p,
int  rad 
)

Definition at line 910 of file animation.cpp.

911 {
912 }

◆ draw_sct()

void game::draw_sct ( ) const

Definition at line 824 of file animation.cpp.

825 {
826  draw_sct_curses( *this );
827 }
void draw_sct_curses(const game &g)
Definition: animation.cpp:790

References anonymous_namespace{animation.cpp}::draw_sct_curses().

Referenced by get_player_input().

◆ draw_ter() [1/2]

void game::draw_ter ( bool  draw_sounds = true)

Definition at line 4130 of file game.cpp.

4131 {
4133  draw_sounds );
4134 }
bool is_looking
Definition: game.h:246

References is_looking, Creature::pos(), u, and Character::view_offset.

Referenced by draw().

◆ draw_ter() [2/2]

void game::draw_ter ( const tripoint center,
bool  looking = false,
bool  draw_sounds = true 
)

Definition at line 4136 of file game.cpp.

4137 {
4138  ter_view_p = center;
4139 
4140  m.draw( w_terrain, center );
4141 
4142  if( draw_sounds ) {
4144  }
4145 
4146  for( Creature &critter : all_creatures() ) {
4147  draw_critter( critter, center );
4148  }
4149 
4150  if( !destination_preview.empty() && u.view_offset.z == 0 ) {
4151  // Draw auto move preview trail
4152  const tripoint_bub_ms &final_destination = destination_preview.back();
4153  tripoint_bub_ms line_center = u.pos_bub() + u.view_offset;
4154  draw_line( final_destination, line_center, destination_preview, true );
4155  // TODO: fix point types
4157  final_destination.xy().raw() - u.view_offset.xy() +
4158  point( POSX - u.posx(), POSY - u.posy() ), c_white, 'X' );
4159  }
4160 
4161  if( u.controlling_vehicle && !looking ) {
4162  draw_veh_dir_indicator( false );
4163  draw_veh_dir_indicator( true );
4164  }
4165 }
void draw_critter(const Creature &critter, const tripoint &center)
Definition: game.cpp:4087
Creature_range all_creatures()
Returns an anonymous range that contains all creatures.
Definition: game.cpp:13223
void draw_veh_dir_indicator(bool next)
Definition: game.cpp:4182
void draw(const catacurses::window &w, const tripoint &center)
Draw a visible part of the map into w.
Definition: map.cpp:6930
static void draw_footsteps(const catacurses::window &window, const tripoint &offset)
Definition: game.cpp:3723

References all_creatures(), c_white, center, Character::controlling_vehicle, destination_preview, map::draw(), draw_critter(), draw_footsteps(), draw_line(), draw_veh_dir_indicator(), m, mvwputch(), Creature::pos_bub(), Creature::posx(), POSX, Creature::posy(), POSY, ter_view_p, tripoint, u, Character::view_offset, w_terrain, coords::coord_point< Point, Origin, Scale, InBounds >::xy(), tripoint::xy(), and tripoint::z.

◆ draw_terrain_override()

void game::draw_terrain_override ( const tripoint p,
const ter_id id 
)

Definition at line 923 of file animation.cpp.

924 {
925 }

◆ draw_trail_to_square()

void game::draw_trail_to_square ( const tripoint t,
bool  bDrawX 
)

Definition at line 8096 of file game.cpp.

8097 {
8098  ::draw_trail( u.pos(), u.pos() + t, bDrawX );
8099 }
static void draw_trail(const tripoint &start, const tripoint &end, bool bDrawX)
Definition: game.cpp:8065

References draw_trail(), Creature::pos(), and u.

◆ draw_trap_override()

void game::draw_trap_override ( const tripoint p,
const trap_id id 
)

Definition at line 962 of file animation.cpp.

963 {
964 }

◆ draw_veh_dir_indicator()

void game::draw_veh_dir_indicator ( bool  next)

Definition at line 4182 of file game.cpp.

4183 {
4184  if( const std::optional<tripoint> indicator_offset = get_veh_dir_indicator_location( next ) ) {
4185  nc_color col = next ? c_white : c_dark_gray;
4186  mvwputch( w_terrain, indicator_offset->xy() - u.view_offset.xy() + point( POSX, POSY ), col, 'X' );
4187  }
4188 }
std::optional< tripoint > get_veh_dir_indicator_location(bool next) const
Returns the location where the indicator should go relative to the reality bubble,...
Definition: game.cpp:4167

References c_dark_gray, c_white, get_veh_dir_indicator_location(), mvwputch(), POSX, POSY, u, Character::view_offset, w_terrain, and tripoint::xy().

Referenced by draw_ter().

◆ draw_vpart_override()

void game::draw_vpart_override ( const tripoint p,
const vpart_id id,
int  part_mod,
const units::angle veh_dir,
bool  hilite,
const point mount 
)

Definition at line 1005 of file animation.cpp.

1007 {
1008 }

◆ draw_weather()

void game::draw_weather ( const weather_printable wPrint) const

Definition at line 782 of file animation.cpp.

783 {
785 }
void draw_weather_curses(const catacurses::window &win, const weather_printable &w)
Definition: animation.cpp:763

References anonymous_namespace{animation.cpp}::draw_weather_curses(), and w_terrain.

Referenced by get_player_input().

◆ draw_zones()

void game::draw_zones ( const tripoint start,
const tripoint end,
const tripoint offset 
) const

Definition at line 859 of file animation.cpp.

860 {
861  draw_zones_curses( w_terrain, start, end, offset );
862 }
void draw_zones_curses(const catacurses::window &w, const tripoint &start, const tripoint &end, const tripoint &offset)
Definition: animation.cpp:832
@ end
Definition: input.h:95

References anonymous_namespace{animation.cpp}::draw_zones_curses(), keycode::end, and w_terrain.

◆ drop_in_direction()

void game::drop_in_direction ( const tripoint pnt)
private

Definition at line 9336 of file game.cpp.

9337 {
9338  u.drop( game_menus::inv::multidrop( u ), pnt );
9339 }
void drop(item_location loc, const tripoint &where)
Drops an item to the specified location.
drop_locations multidrop(Character &you)
Select items to drop.

References Character::drop(), game_menus::inv::multidrop(), and u.

Referenced by do_regular_action().

◆ events()

event_bus & game::events ( )
private

Definition at line 3422 of file game.cpp.

3423 {
3424  return *event_bus_ptr;
3425 }
pimpl< event_bus > event_bus_ptr
Definition: game.h:1069

References event_bus_ptr.

Referenced by game(), is_game_over(), load(), and save().

◆ exam_appliance()

void game::exam_appliance ( vehicle veh,
const point cp = point_zero 
)

open appliance interaction screen

Definition at line 5649 of file game.cpp.

5650 {
5652  if( act ) {
5653  u.set_moves( 0 );
5654  u.assign_activity( act );
5655  }
5656 }
static player_activity run(vehicle &veh, const point &p=point_zero)
Starts and manages the appliance interaction UI.
static constexpr double c
Definition: magic.cpp:1568

References act, Character::assign_activity(), c, veh_app_interact::run(), Creature::set_moves(), and u.

◆ exam_vehicle()

void game::exam_vehicle ( vehicle veh,
const point cp = point_zero 
)

open vehicle interaction screen

Definition at line 5658 of file game.cpp.

5659 {
5660  if( veh.magic ) {
5661  add_msg( m_info, _( "This is your %s" ), veh.name );
5662  return;
5663  }
5665  if( act ) {
5666  u.set_moves( 0 );
5667  u.assign_activity( act );
5668  }
5669 }
static player_activity run(vehicle &veh, const point &p)

References _, act, add_msg(), Character::assign_activity(), c, m_info, vehicle::magic, vehicle::name, veh_interact::run(), Creature::set_moves(), and u.

◆ examine() [1/2]

void game::examine ( bool  with_pickup = true)
private

Definition at line 6090 of file game.cpp.

6091 {
6092  // if we are driving a vehicle, examine the
6093  // current tile without asking.
6094  const optional_vpart_position vp = m.veh_at( u.pos() );
6095  if( vp && vp->vehicle().player_in_control( u ) ) {
6096  examine( u.pos(), with_pickup );
6097  return;
6098  }
6099 
6100  std::optional<tripoint> examp;
6101  if( with_pickup ) {
6102  // Examine and/or pick up items
6103  examp = choose_adjacent_highlight( _( "Examine terrain, furniture, or items where?" ),
6104  _( "There is nothing that can be examined nearby." ),
6105  ACTION_EXAMINE_AND_PICKUP, false );
6106  } else {
6107  // Examine but do not pick up items
6108  examp = choose_adjacent_highlight( _( "Examine terrain or furniture where?" ),
6109  _( "There is nothing that can be examined nearby." ),
6110  ACTION_EXAMINE, false );
6111  }
6112 
6113  if( !examp ) {
6114  return;
6115  }
6116  u.manual_examine = true;
6117  examine( *examp, with_pickup );
6118  u.manual_examine = false;
6119 }
std::optional< tripoint > choose_adjacent_highlight(const std::string &message, const std::string &failure_message, const action_id action, const bool allow_vertical, const bool allow_autoselect)
Request player input of adjacent tile with highlighting, possibly on different z-level.
Definition: action.cpp:1212
bool manual_examine
Definition: character.h:599

References _, ACTION_EXAMINE, ACTION_EXAMINE_AND_PICKUP, choose_adjacent_highlight(), examine(), m, Character::manual_examine, Creature::pos(), u, and map::veh_at().

◆ examine() [2/2]

void game::examine ( const tripoint p,
bool  with_pickup = false 
)
private

Definition at line 6188 of file game.cpp.

6189 {
6190  if( disable_robot( examp ) ) {
6191  return;
6192  }
6193 
6195  if( c != nullptr ) {
6196  monster *mon = dynamic_cast<monster *>( c );
6197  if( mon != nullptr ) {
6198  add_msg( _( "There is a %s." ), mon->get_name() );
6199  if( mon->has_effect( effect_pet ) && !u.is_mounted() ) {
6200  if( monexamine::pet_menu( *mon ) ) {
6201  return;
6202  }
6203  } else if( mon->has_flag( mon_flag_RIDEABLE_MECH ) && !mon->has_effect( effect_pet ) ) {
6204  if( monexamine::mech_hack( *mon ) ) {
6205  return;
6206  }
6207  } else if( mon->has_flag( mon_flag_PAY_BOT ) ) {
6208  if( monexamine::pay_bot( *mon ) ) {
6209  return;
6210  }
6211  } else if( mon->attitude_to( u ) == Creature::Attitude::FRIENDLY && !u.is_mounted() ) {
6212  if( monexamine::mfriend_menu( *mon ) ) {
6213  return;
6214  }
6215  } else if( mon->has_flag( mon_flag_CONVERSATION ) && !mon->type->chat_topics.empty() ) {
6216  get_avatar().talk_to( get_talker_for( mon ) );
6217  }
6218  } else {
6219  u.cant_do_mounted();
6220  }
6221  npc *np = dynamic_cast<npc *>( c );
6222  if( np != nullptr && !u.cant_do_mounted() ) {
6223  if( npc_menu( *np ) ) {
6224  return;
6225  }
6226  }
6227  }
6228 
6229  const optional_vpart_position vp = m.veh_at( examp );
6230  if( vp ) {
6231  if( !u.is_mounted() || u.mounted_creature->has_flag( mon_flag_RIDEABLE_MECH ) ) {
6232  if( !vp->vehicle().is_appliance() ) {
6233  vp->vehicle().interact_with( examp, with_pickup );
6234  } else {
6235  g->exam_appliance( vp->vehicle(), vp->mount() );
6236  }
6237  return;
6238  } else {
6239  add_msg( m_warning, _( "You cannot interact with a vehicle while mounted." ) );
6240  }
6241  }
6242 
6243  iexamine::part_con( get_avatar(), examp );
6244  // trap::iexamine will handle the invisible traps.
6245  m.tr_at( examp ).examine( examp );
6246 
6247  if( m.has_flag( ter_furn_flag::TFLAG_CONSOLE, examp ) && !u.is_mounted() ) {
6248  use_computer( examp );
6249  return;
6250  } else if( m.has_flag( ter_furn_flag::TFLAG_CONSOLE, examp ) && u.is_mounted() ) {
6251  add_msg( m_warning, _( "You cannot use a console while mounted." ) );
6252  }
6253  const furn_t &xfurn_t = m.furn( examp ).obj();
6254  const ter_t &xter_t = m.ter( examp ).obj();
6255 
6256  const tripoint player_pos = u.pos();
6257 
6258  if( m.has_furn( examp ) ) {
6259  if( !u.cant_do_mounted() ) {
6260  xfurn_t.examine( u, examp );
6261  }
6262  } else {
6263  if( xter_t.can_examine( examp ) && !u.is_mounted() ) {
6264  xter_t.examine( u, examp );
6265  }
6266  }
6267 
6268  // Did the player get moved? Bail out if so; our examp probably
6269  // isn't valid anymore.
6270  if( player_pos != u.pos() ) {
6271  return;
6272  }
6273 
6274  bool none = true;
6275  if( xter_t.can_examine( examp ) || xfurn_t.can_examine( examp ) ) {
6276  none = false;
6277  }
6278 
6279  // In case of teleport trap or somesuch
6280  if( player_pos != u.pos() ) {
6281  return;
6282  }
6283 
6284  // Feedback for fire lasting time, this can be judged while mounted
6285  const std::string fire_fuel = get_fire_fuel_string( examp );
6286  if( !fire_fuel.empty() ) {
6287  add_msg( fire_fuel );
6288  }
6289 
6290  if( m.has_flag( ter_furn_flag::TFLAG_SEALED, examp ) ) {
6291  if( none ) {
6292  if( m.has_flag( ter_furn_flag::TFLAG_UNSTABLE, examp ) ) {
6293  add_msg( _( "The %s is too unstable to remove anything." ), m.name( examp ) );
6294  } else {
6295  add_msg( _( "The %s is firmly sealed." ), m.name( examp ) );
6296  }
6297  }
6298  } else {
6299  //examp has no traps, is a container and doesn't have a special examination function
6300  if( m.tr_at( examp ).is_null() && m.i_at( examp ).empty() &&
6302  add_msg( _( "It is empty." ) );
6303  } else if( ( m.has_flag( ter_furn_flag::TFLAG_FIRE_CONTAINER, examp ) &&
6304  xfurn_t.has_examine( iexamine::fireplace ) ) ||
6305  xfurn_t.has_examine( iexamine::workbench ) ) {
6306  return;
6307  } else {
6309  // Pick up items, if there are any, unless there is reason to not to
6310  if( with_pickup && m.has_items( examp ) && !u.is_mounted() &&
6312  !m.only_liquid_in_liquidcont( examp ) ) {
6313  pickup( examp );
6314  }
6315  }
6316  }
6317 }
bool cant_do_mounted(bool msg=true) const
Definition: character.cpp:1720
void use_computer(const tripoint &p)
Checks to see if a player can use a computer (not illiterate, etc.) and uses if able.
Definition: game.cpp:5084
bool disable_robot(const tripoint &p)
If there is a robot (that can be disabled), query the player and try to disable it.
Definition: game.cpp:10373
bool npc_menu(npc &who)
Returns true if the menu handled stuff and player shouldn't do anything else.
Definition: game.cpp:5941
const T & obj() const
Definition: ammo_effect.cpp:26
bool empty() const
Definition: item_stack.cpp:19
bool only_liquid_in_liquidcont(const tripoint &p)
Definition: map.cpp:5911
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:5890
ter_id ter(const tripoint &p) const
Definition: map.cpp:1922
furn_id furn(const tripoint &p) const
Definition: map.cpp:1722
Attitude attitude_to(const Creature &other) const override
Attitude (of this creature) towards another creature.
Definition: monster.cpp:1450
std::string get_name() const override
Definition: monster.cpp:717
static const efftype_id effect_pet("pet")
static std::string get_fire_fuel_string(const tripoint &examp)
Definition: game.cpp:6121
@ TFLAG_NO_PICKUP_ON_EXAMINE
mon_flag_id mon_flag_PAY_BOT
Definition: mtype.cpp:126
void workbench(Character &you, const tripoint &examp)
Definition: iexamine.cpp:7156
void fireplace(Character &you, const tripoint &examp)
Definition: iexamine.cpp:3387
void part_con(Character &you, const tripoint &examp)
Definition: iexamine.cpp:4630
bool pet_menu(monster &z)
Definition: monexamine.cpp:578
bool mech_hack(monster &z)
Definition: monexamine.cpp:854
bool mfriend_menu(monster &z)
Definition: monexamine.cpp:928
bool pay_bot(monster &z)
Definition: monexamine.cpp:887
void process_sound_markers(Character *you)
Definition: sounds.cpp:569
bool has_examine(iexamine_examine_function func) const
Definition: mapdata.cpp:573
void examine(Character &, const tripoint &) const
Definition: mapdata.cpp:588
bool can_examine(const tripoint &examp) const
Definition: mapdata.cpp:568
Definition: mapdata.h:598
void examine(const tripoint &examp) const
Called when the player examines a tile.
Definition: iexamine.cpp:4535

References _, add_msg(), monster::attitude_to(), c, map_data_common_t::can_examine(), Character::cant_do_mounted(), mtype::chat_topics, creature_tracker::creature_at(), disable_robot(), effect_pet, item_stack::empty(), map_data_common_t::examine(), trap::examine(), iexamine::fireplace(), Creature::FRIENDLY, map::furn(), g, get_avatar, get_creature_tracker, get_fire_fuel_string(), monster::get_name(), get_talker_for(), Creature::has_effect(), map_data_common_t::has_examine(), monster::has_flag(), map::has_flag(), map::has_furn(), map::has_items(), map::i_at(), Character::is_mounted(), trap::is_null(), m, m_warning, monexamine::mech_hack(), monexamine::mfriend_menu(), mon_flag_CONVERSATION, mon_flag_PAY_BOT, mon_flag_RIDEABLE_MECH, Character::mounted_creature, map::name(), none, npc_menu(), int_id< T >::obj(), map::only_liquid_in_liquidcont(), iexamine::part_con(), monexamine::pay_bot(), monexamine::pet_menu(), pickup(), Creature::pos(), sounds::process_sound_markers(), avatar::talk_to(), map::ter(), TFLAG_CONSOLE, TFLAG_CONTAINER, TFLAG_FIRE_CONTAINER, TFLAG_NO_PICKUP_ON_EXAMINE, TFLAG_SEALED, TFLAG_UNSTABLE, map::tr_at(), monster::type, u, use_computer(), map::veh_at(), and iexamine::workbench().

Referenced by do_regular_action(), and examine().

◆ extended_description()

void game::extended_description ( const tripoint p)

Long description of (visible) things at tile.

Definition at line 49 of file descriptions.cpp.

50 {
51  ui_adaptor ui;
52  const int top = 3;
53  int width = 0;
54  catacurses::window w_head;
55  catacurses::window w_main;
56  ui.on_screen_resize( [&]( ui_adaptor & ui ) {
57  const int left = 0;
58  const int right = TERMX;
59  const int bottom = TERMY;
60  width = right - left;
61  const int height = bottom - top;
62  w_head = catacurses::newwin( top, TERMX, point_zero );
63  w_main = catacurses::newwin( height, width, point( left, top ) );
64  ui.position( point_zero, point( TERMX, TERMY ) );
65  } );
66  ui.mark_resize();
67 
68  // Default to critter (if any), furniture (if any), then terrain.
70  if( seen_critter( p ) != nullptr ) {
71  cur_target = description_target::creature;
72  } else if( get_map().has_furn( p ) ) {
73  cur_target = description_target::furniture;
74  }
75 
76  std::string action;
77  input_context ctxt( "EXTENDED_DESCRIPTION" );
78  ctxt.register_action( "CREATURE" );
79  ctxt.register_action( "FURNITURE" );
80  ctxt.register_action( "TERRAIN" );
81  ctxt.register_action( "VEHICLE" );
82  ctxt.register_action( "CONFIRM" );
83  ctxt.register_action( "QUIT" );
84  ctxt.register_action( "HELP_KEYBINDINGS" );
85 
86  ui.on_redraw( [&]( const ui_adaptor & ) {
87  werase( w_head );
88  mvwprintz( w_head, point_zero, c_white,
89  _( "[%s] describe creatures, [%s] describe furniture, "
90  "[%s] describe terrain, [%s] describe vehicle/appliance, [%s] close." ),
91  ctxt.get_desc( "CREATURE" ), ctxt.get_desc( "FURNITURE" ),
92  ctxt.get_desc( "TERRAIN" ), ctxt.get_desc( "VEHICLE" ), ctxt.get_desc( "QUIT" ) );
93 
94  // Set up line drawings
95  for( int i = 0; i < TERMX; i++ ) {
96  mvwputch( w_head, point( i, top - 1 ), c_white, LINE_OXOX );
97  }
98 
99  wnoutrefresh( w_head );
100 
101  std::string desc;
102  // Allow looking at invisible tiles - player may want to examine hallucinations etc.
103  switch( cur_target ) {
105  const Creature *critter = seen_critter( p );
106  if( critter != nullptr ) {
107  desc = critter->extended_description();
108  } else {
109  desc = _( "You do not see any creature here." );
110  }
111  }
112  break;
114  if( !u.sees( p ) || !m.has_furn( p ) ) {
115  desc = _( "You do not see any furniture here." );
116  } else {
117  const furn_id fid = m.furn( p );
118  const std::string mod_src = enumerate_as_string( fid->src.begin(),
119  fid->src.end(), []( const std::pair<furn_str_id, mod_id> &source ) {
120  return string_format( "'%s'", source.second->name() );
122  desc = string_format( _( "Origin: %s\n%s" ), mod_src, fid->extended_description() );
123  }
124  break;
126  if( !u.sees( p ) ) {
127  desc = _( "You can't see the terrain here." );
128  } else {
129  const ter_id tid = m.ter( p );
130  const std::string mod_src = enumerate_as_string( tid->src.begin(),
131  tid->src.end(), []( const std::pair<ter_str_id, mod_id> &source ) {
132  return string_format( "'%s'", source.second->name() );
134  desc = string_format( _( "Origin: %s\n%s" ), mod_src, tid->extended_description() );
135  }
136  break;
138  const optional_vpart_position vp = m.veh_at( p );
139  if( !u.sees( p ) || !vp ) {
140  desc = _( "You can't see vehicles or appliances here." );
141  } else {
142  desc = vp.extended_description();
143  }
144  break;
145  }
146 
147  std::string signage = m.get_signage( p );
148  if( !signage.empty() ) {
149  // NOLINTNEXTLINE(cata-text-style): the question mark does not end a sentence
150  desc += u.has_trait( trait_ILLITERATE ) ? _( "\nSign: ???" ) : string_format( _( "\nSign: %s" ),
151  signage );
152  }
153 
154  werase( w_main );
155  fold_and_print_from( w_main, point_zero, width, 0, c_light_gray, desc );
156  wnoutrefresh( w_main );
157  } );
158 
159  do {
161  action = ctxt.handle_input();
162  if( action == "CREATURE" ) {
163  cur_target = description_target::creature;
164  } else if( action == "FURNITURE" ) {
165  cur_target = description_target::furniture;
166  } else if( action == "TERRAIN" ) {
167  cur_target = description_target::terrain;
168  } else if( action == "VEHICLE" ) {
169  cur_target = description_target::vehicle;
170  }
171  } while( action != "CONFIRM" && action != "QUIT" );
172 }
virtual std::string extended_description() const =0
std::string get_signage(const tripoint &p) const
Definition: map.cpp:4849
std::string extended_description() const
Definition: vehicle.cpp:2743
static const trait_id trait_ILLITERATE("ILLITERATE")
static const Creature * seen_critter(const tripoint &p)
description_target
int fold_and_print_from(const catacurses::window &w, const point &begin, int width, int begin_line, const nc_color &base_color, const std::string &text)
Like fold_and_print, but starts the output with the N-th line of the folded string.
Definition: output.cpp:391
std::string enumerate_as_string(const Container &values, enumeration_conjunction conj=enumeration_conjunction::and_)
Definition: output.h:647
std::vector< std::pair< furn_str_id, mod_id > > src
Definition: mapdata.h:643
std::string extended_description() const
std::vector< std::pair< ter_str_id, mod_id > > src
Definition: mapdata.h:600

References _, action, arrow, c_light_gray, c_white, creature, enumerate_as_string(), map_data_common_t::extended_description(), optional_vpart_position::extended_description(), Creature::extended_description(), fold_and_print_from(), map::furn(), furniture, input_context::get_desc(), get_map, map::get_signage(), input_context::handle_input(), map::has_furn(), Character::has_trait(), left, LINE_OXOX, m, mvwprintz(), mvwputch(), catacurses::newwin(), point, point_zero, ui_manager::redraw(), input_context::register_action(), right, seen_critter(), Character::sees(), ter_t::src, furn_t::src, string_format(), map::ter(), TERMX, TERMY, terrain, trait_ILLITERATE, u, map::veh_at(), vehicle, catacurses::werase(), and catacurses::wnoutrefresh().

Referenced by look_around().

◆ find_nearby_items()

std::vector< map_item_stack > game::find_nearby_items ( int  iRadius)
private

Definition at line 8035 of file game.cpp.

8036 {
8037  std::map<std::string, map_item_stack> temp_items;
8038  std::vector<map_item_stack> ret;
8039  std::vector<std::string> item_order;
8040 
8041  if( u.is_blind() ) {
8042  return ret;
8043  }
8044 
8045  for( tripoint &points_p_it : closest_points_first( u.pos(), iRadius ) ) {
8046  if( points_p_it.y >= u.posy() - iRadius && points_p_it.y <= u.posy() + iRadius &&
8047  u.sees( points_p_it ) &&
8048  m.sees_some_items( points_p_it, u ) ) {
8049 
8050  for( item &elem : m.i_at( points_p_it ) ) {
8051  const tripoint relative_pos = points_p_it - u.pos();
8052 
8053  add_item_recursive( item_order, temp_items, &elem, relative_pos );
8054  }
8055  }
8056  }
8057 
8058  for( auto &elem : item_order ) {
8059  ret.push_back( temp_items[elem] );
8060  }
8061 
8062  return ret;
8063 }
std::vector< coords::coord_point< Point, Origin, Scale > > closest_points_first(const coords::coord_point< Point, Origin, Scale > &loc, int min_dist, int max_dist)
Definition: coordinates.h:848
static void add_item_recursive(std::vector< std::string > &item_order, std::map< std::string, map_item_stack > &temp_items, const item *it, const tripoint &relative_pos)
Definition: game.cpp:8018

References add_item_recursive(), closest_points_first(), map::i_at(), Character::is_blind(), m, Creature::pos(), Creature::posy(), cata::hash64_detail::ret, Character::sees(), map::sees_some_items(), and u.

Referenced by list_items_monsters().

◆ find_nearby_spawn_point() [1/2]

bool game::find_nearby_spawn_point ( const tripoint target,
const mtype_id mt,
int  min_radius,
int  max_radius,
tripoint point,
bool  outdoor_only,
bool  indoor_only,
bool  open_air_allowed = false 
)

Finds somewhere to spawn a monster or npc.

Definition at line 5295 of file game.cpp.

5297 {
5298  tripoint target_point;
5299  //find a legal outdoor place to spawn based on the specified radius,
5300  //we just try a bunch of random points and use the first one that works, it none do then no spawn
5301  for( int attempts = 0; attempts < 75; attempts++ ) {
5302  target_point = target + tripoint( rng( -max_radius, max_radius ),
5303  rng( -max_radius, max_radius ), 0 );
5304  if( can_place_monster( monster( mt->id ), target_point ) &&
5305  ( open_air_allowed || get_map().has_floor_or_water( target_point ) ) &&
5306  ( !outdoor_only || get_map().is_outside( target_point ) ) &&
5307  ( !indoor_only || !get_map().is_outside( target_point ) ) &&
5308  rl_dist( target_point, target ) >= min_radius ) {
5309  point = target_point;
5310  return true;
5311  }
5312  }
5313  return false;
5314 }
static bool can_place_monster(const monster &mon, const tripoint &p)
Definition: game.cpp:5169

References can_place_monster(), get_map, mtype::id, rl_dist(), rng(), and tripoint.

◆ find_nearby_spawn_point() [2/2]

bool game::find_nearby_spawn_point ( const tripoint target,
int  min_radius,
int  max_radius,
tripoint point,
bool  outdoor_only,
bool  indoor_only,
bool  open_air_allowed = false 
)

Definition at line 5316 of file game.cpp.

5318 {
5319  tripoint target_point;
5320  //find a legal outdoor place to spawn based on the specified radius,
5321  //we just try a bunch of random points and use the first one that works, it none do then no spawn
5322  for( int attempts = 0; attempts < 75; attempts++ ) {
5323  target_point = target + tripoint( rng( -max_radius, max_radius ),
5324  rng( -max_radius, max_radius ), 0 );
5325  if( can_place_npc( target_point ) &&
5326  ( open_air_allowed || get_map().has_floor_or_water( target_point ) ) &&
5327  ( !outdoor_only || get_map().is_outside( target_point ) ) &&
5328  ( !indoor_only || !get_map().is_outside( target_point ) ) &&
5329  rl_dist( target_point, target ) >= min_radius ) {
5330  point = target_point;
5331  return true;
5332  }
5333  }
5334  return false;
5335 }
static bool can_place_npc(const tripoint &p)
Definition: game.cpp:5186

References can_place_npc(), get_map, rl_dist(), rng(), and tripoint.

◆ find_npc()

npc * game::find_npc ( character_id  id)

Find the npc with the given ID.

Returns NULL if the npc could not be found. Searches all loaded overmaps.

Definition at line 1715 of file game.cpp.

1716 {
1717  return overmap_buffer.find_npc( id ).get();
1718 }

References overmapbuffer::find_npc(), and overmap_buffer.

Referenced by critter_by_id().

◆ find_npc_by_unique_id()

npc * game::find_npc_by_unique_id ( const std::string &  unique_id)

Find the npc with the given unique ID.

Returns NULL if the npc could not be found. Searches all loaded overmaps.

Definition at line 1720 of file game.cpp.

1721 {
1722  return overmap_buffer.find_npc_by_unique_id( unique_id ).get();
1723 }
shared_ptr_fast< npc > find_npc_by_unique_id(const std::string &unique_id)

References overmapbuffer::find_npc_by_unique_id(), and overmap_buffer.

◆ find_or_make_stairs()

std::optional< tripoint > game::find_or_make_stairs ( map mp,
int  z_after,
bool &  rope_ladder,
bool  peeking,
const tripoint pos 
)

Returns the other end of the stairs (if any).

May query, affect u etc.

Parameters
posDisable queries and msgs if not the same position as player.

Definition at line 12386 of file game.cpp.

12388 {
12389  const bool is_avatar = u.pos() == pos;
12390  const int omtilesz = SEEX * 2;
12391  real_coords rc( mp.getabs( pos.xy() ) );
12392  tripoint omtile_align_start( mp.getlocal( rc.begin_om_pos() ), z_after );
12393  tripoint omtile_align_end( omtile_align_start + point( -1 + omtilesz, -1 + omtilesz ) );
12394 
12395  // Try to find the stairs.
12396  std::optional<tripoint> stairs;
12397  int best = INT_MAX;
12398  const int movez = z_after - pos.z;
12399  const bool going_down_1 = movez == -1;
12400  const bool going_up_1 = movez == 1;
12401  // If there are stairs on the same x and y as we currently are, use those
12402  if( going_down_1 && mp.has_flag( ter_furn_flag::TFLAG_GOES_UP, pos + tripoint_below ) ) {
12403  stairs.emplace( pos + tripoint_below );
12404  }
12405  if( going_up_1 && mp.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, pos + tripoint_above ) ) {
12406  stairs.emplace( pos + tripoint_above );
12407  }
12408  // We did not find stairs directly above or below, so search the map for them
12409  // If there's empty space right below us, we can just go down that way.
12410  if( !stairs.has_value() && get_map().tr_at( u.pos() ) != tr_ledge ) {
12411  for( const tripoint &dest : mp.points_in_rectangle( omtile_align_start, omtile_align_end ) ) {
12412  if( rl_dist( u.pos(), dest ) <= best &&
12413  ( ( going_down_1 && mp.has_flag( ter_furn_flag::TFLAG_GOES_UP, dest ) ) ||
12414  ( going_up_1 && ( mp.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, dest ) ||
12415  mp.ter( dest ) == ter_t_manhole_cover ) ) ||
12416  ( ( movez == 2 || movez == -2 ) && mp.ter( dest ) == ter_t_elevator ) ) ) {
12417  stairs.emplace( dest );
12418  best = rl_dist( u.pos(), dest );
12419  }
12420  }
12421  }
12422 
12423  creature_tracker &creatures = get_creature_tracker();
12424  if( stairs.has_value() ) {
12425  if( !is_avatar ) {
12426  return stairs;
12427  }
12428  if( Creature *blocking_creature = creatures.creature_at( stairs.value() ) ) {
12429  npc *guy = dynamic_cast<npc *>( blocking_creature );
12430  monster *mon = dynamic_cast<monster *>( blocking_creature );
12431  bool would_move = ( guy && !guy->is_enemy() ) || ( mon && mon->friendly == -1 );
12432  std::string cr_name = blocking_creature->get_name();
12433  std::string msg;
12434  if( guy ) {
12435  //~ %s is the name of hostile NPC
12436  msg = string_format( _( "%s is in the way!" ), cr_name );
12437  } else {
12438  //~ %s is some monster
12439  msg = string_format( _( "There's a %s in the way!" ), cr_name );
12440  }
12441 
12442  if( ( peeking && !would_move )
12443  || ( !would_move && !query_yn(
12444  //~ %s is a warning about monster/hostile NPC in the way, e.g. "There's a zombie in the way!"
12445  _( "%s Attempt to push past? You may have to fight your way back up." ), msg ) ) ) {
12446  add_msg( msg );
12447  return std::nullopt;
12448  }
12449  }
12450  return stairs;
12451  }
12452 
12453  if( !is_avatar || peeking ) {
12454  return std::nullopt;
12455  }
12456  // No stairs found! Try to make some
12457  rope_ladder = false;
12458  stairs.emplace( pos );
12459  stairs->z = z_after;
12460  // Check the destination area for lava.
12461  if( mp.ter( *stairs ) == ter_t_lava ) {
12462  if( movez < 0 &&
12463  !query_yn(
12464  _( "There is a LOT of heat coming out of there, even the stairs have melted away. Jump down? You won't be able to get back up." ) ) ) {
12465  return std::nullopt;
12466  }
12467  if( movez > 0 &&
12468  !query_yn(
12469  _( "There is a LOT of heat coming out of there. Push through the half-molten rocks and ascend? You will not be able to get back down." ) ) ) {
12470  return std::nullopt;
12471  }
12472 
12473  return stairs;
12474  }
12475 
12476  if( u.has_effect( effect_gliding ) && get_map().tr_at( u.pos() ) == tr_ledge ) {
12477  return stairs;
12478  }
12479 
12480  if( movez > 0 ) {
12481  if( !mp.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, *stairs ) ) {
12482  if( !query_yn( _( "You may be unable to return back down these stairs. Continue up?" ) ) ) {
12483  return std::nullopt;
12484  }
12485  }
12486  // Manhole covers need this to work
12487  // Maybe require manhole cover here and fail otherwise?
12488  return stairs;
12489  }
12490 
12491  if( mp.impassable( *stairs ) ) {
12492  popup( _( "Halfway down, the way down becomes blocked off." ) );
12493  return std::nullopt;
12494  }
12495 
12496  if( u.has_flag( json_flag_WEB_RAPPEL ) ) {
12497  if( query_yn( _( "There is a sheer drop halfway down. Web-descend?" ) ) ) {
12498  rope_ladder = true;
12499  if( rng( 4, 8 ) < u.get_skill_level( skill_dodge ) ) {
12500  add_msg( _( "You attach a web and dive down headfirst, flipping upright and landing on your feet." ) );
12501  } else {
12502  add_msg( _( "You securely web up and work your way down, lowering yourself safely." ) );
12503  }
12504  } else {
12505  return std::nullopt;
12506  }
12507  } else if( u.has_trait( trait_VINES2 ) || u.has_trait( trait_VINES3 ) ) {
12508  if( query_yn( _( "There is a sheer drop halfway down. Use your vines to descend?" ) ) ) {
12509  if( u.has_trait( trait_VINES2 ) ) {
12510  if( query_yn( _( "Detach a vine? It'll hurt, but you'll be able to climb back up…" ) ) ) {
12511  rope_ladder = true;
12512  add_msg( m_bad, _( "You descend on your vines, though leaving a part of you behind stings." ) );
12513  u.mod_pain( 5 );
12514  u.apply_damage( nullptr, bodypart_id( "torso" ), 5 );
12515  u.mod_stored_kcal( -87 );
12516  u.mod_thirst( 10 );
12517  } else {
12518  add_msg( _( "You gingerly descend using your vines." ) );
12519  }
12520  } else {
12521  add_msg( _( "You effortlessly lower yourself and leave a vine rooted for future use." ) );
12522  rope_ladder = true;
12523  u.mod_stored_kcal( -87 );
12524  u.mod_thirst( 10 );
12525  }
12526  } else {
12527  return std::nullopt;
12528  }
12529  } else if( u.has_amount( itype_grapnel, 1 ) ) {
12530  if( query_yn( _( "There is a sheer drop halfway down. Climb your grappling hook down?" ) ) ) {
12531  rope_ladder = true;
12532  for( item &used_item : u.use_amount( itype_grapnel, 1 ) ) {
12533  used_item.spill_contents( u );
12534  }
12535  } else {
12536  return std::nullopt;
12537  }
12538  } else if( u.has_amount( itype_rope_30, 1 ) ) {
12539  if( query_yn( _( "There is a sheer drop halfway down. Climb your rope down?" ) ) ) {
12540  rope_ladder = true;
12541  for( item &used_item : u.use_amount( itype_rope_30, 1 ) ) {
12542  used_item.spill_contents( u );
12543  }
12544  } else {
12545  return std::nullopt;
12546  }
12547  } else if( !query_yn( _( "There is a sheer drop halfway down. Jump?" ) ) ) {
12548  return std::nullopt;
12549  }
12550 
12551  return stairs;
12552 }
bool has_flag(const json_character_flag &flag) const
Returns true if player has a trait, bionic, effect, bodypart, or martial arts buff with a flag.
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:9635
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:9614
tripoint_range< tripoint > points_in_rectangle(const tripoint &from, const tripoint &to) const
Definition: map.cpp:10099
int friendly
Definition: monster.h:539
bool is_enemy() const
Definition: npc.cpp:2352
@ m_bad
Definition: enums.h:348
static const trait_id trait_VINES2("VINES2")
static const ter_str_id ter_t_manhole_cover("t_manhole_cover")
static const skill_id skill_dodge("dodge")
static const itype_id itype_rope_30("rope_30")
static const ter_str_id ter_t_elevator("t_elevator")
static const itype_id itype_grapnel("grapnel")
static const ter_str_id ter_t_lava("t_lava")
static const trait_id trait_VINES3("VINES3")
static const efftype_id effect_gliding("gliding")
static const json_character_flag json_flag_WEB_RAPPEL("WEB_RAPPEL")
const trap_str_id tr_ledge("tr_ledge")

References _, add_msg(), Character::apply_damage(), real_coords::begin_om_pos(), creature_tracker::creature_at(), effect_gliding, monster::friendly, get_creature_tracker, get_map, monster::get_name(), Character::get_skill_level(), map::getabs(), map::getlocal(), visitable::has_amount(), Creature::has_effect(), Character::has_flag(), map::has_flag(), Character::has_trait(), map::impassable(), npc::is_enemy(), itype_grapnel, itype_rope_30, json_flag_WEB_RAPPEL, m_bad, Character::mod_pain(), Character::mod_stored_kcal(), Character::mod_thirst(), point, map::points_in_rectangle(), popup(), Creature::pos(), math_opers::pos(), query_yn(), rl_dist(), rng(), SEEX, skill_dodge, string_format(), map::ter(), ter_t_elevator, ter_t_lava, ter_t_manhole_cover, TFLAG_GOES_DOWN, TFLAG_GOES_UP, tr_ledge, trait_VINES2, trait_VINES3, tripoint_above, tripoint_below, u, and Character::use_amount().

Referenced by vertical_move().

◆ fling_creature()

bool game::fling_creature ( Creature c,
const units::angle dir,
float  flvel,
bool  controlled = false,
bool  intentional = false 
)

Flings the input creature in the given direction.

intentional is true for activities you wouldn't consider immunity for

Definition at line 11735 of file game.cpp.

11737 {
11738  if( c == nullptr ) {
11739  debugmsg( "game::fling_creature invoked on null target" );
11740  return false;
11741  }
11742 
11743  if( c->is_dead_state() ) {
11744  // Flinging a corpse causes problems, don't enable without testing
11745  return false;
11746  }
11747 
11748  if( c->is_hallucination() ) {
11749  // Don't fling hallucinations
11750  return false;
11751  }
11752 
11753  // Target creature shouldn't be grabbed if thrown
11754  // It should also not be thrown if the throw is weaker than the grab
11755  for( const effect &eff : c->get_effects_with_flag( json_flag_GRAB ) ) {
11756  if( !x_in_y( flvel / 2, eff.get_intensity() ) ) {
11757  c->add_msg_player_or_npc( m_warning,
11758  _( "You're almost sent flying, but something holds you in place!" ),
11759  _( "<npcname> is almost sent flying, but something holds them in place!" ) );
11760  return false;
11761  } else {
11762  c->remove_effect( eff.get_id(), eff.get_bp() );
11763  }
11764  }
11765 
11766  bool thru = true;
11767  const bool is_u = c == &u;
11768  // Don't animate critters getting bashed if animations are off
11769  const bool animate = is_u || get_option<bool>( "ANIMATIONS" );
11770 
11771  Character *you = dynamic_cast<Character *>( c );
11772 
11773  // at this point we should check if knockback immune
11774  // assuming that the shove wasn't intentional
11775  if( !intentional && you != nullptr ) {
11776 
11777  double knockback_resist = 0.0;
11778  knockback_resist = you->calculate_by_enchantment( knockback_resist,
11780  if( knockback_resist >= 1 ) {
11781  // you are immune
11782  return false;
11783  }
11784 
11785  // 1.0 knockback resist is immune, 0 is normal
11786  flvel *= 1 - knockback_resist;
11787  }
11788 
11789  tileray tdir( dir );
11790  int range = flvel / 10;
11791  tripoint pt = c->pos();
11792  creature_tracker &creatures = get_creature_tracker();
11793  while( range > 0 ) {
11794  c->underwater = false;
11795  // TODO: Check whenever it is actually in the viewport
11796  // or maybe even just redraw the changed tiles
11797  bool seen = is_u || u.sees( *c ); // To avoid redrawing when not seen
11798  tdir.advance();
11799  pt.x = c->posx() + tdir.dx();
11800  pt.y = c->posy() + tdir.dy();
11801  float force = 0.0f;
11802 
11803  if( monster *const mon_ptr = creatures.creature_at<monster>( pt ) ) {
11804  monster &critter = *mon_ptr;
11805  // Approximate critter's "stopping power" with its max hp
11806  force = std::min<float>( 1.5f * critter.type->hp, flvel );
11807  const int damage = rng( force, force * 2.0f ) / 6;
11808  c->impact( damage, pt );
11809  // Multiply zed damage by 6 because no body parts
11810  const int zed_damage = std::max( 0,
11811  ( damage - critter.get_armor_type( damage_bash, bodypart_id( "torso" ) ) ) * 6 );
11812  // TODO: Pass the "flinger" here - it's not the flung critter that deals damage
11813  critter.apply_damage( c, bodypart_id( "torso" ), zed_damage );
11814  critter.check_dead_state();
11815  if( !critter.is_dead() ) {
11816  thru = false;
11817  }
11818  } else if( m.impassable( pt ) ) {
11819  if( !m.veh_at( pt ).obstacle_at_part() ) {
11820  force = std::min<float>( m.bash_strength( pt ), flvel );
11821  } else {
11822  // No good way of limiting force here
11823  // Keep it 1 less than maximum to make the impact hurt
11824  // but to keep the target flying after it
11825  force = flvel - 1;
11826  }
11827  const int damage = rng( force, force * 2.0f ) / 9;
11828  c->impact( damage, pt );
11829  if( m.is_bashable( pt ) ) {
11830  // Only go through if we successfully make the tile passable
11831  m.bash( pt, flvel );
11832  thru = m.passable( pt );
11833  } else {
11834  thru = false;
11835  }
11836  }
11837 
11838  // If the critter dies during flinging, moving it around causes debugmsgs
11839  if( c->is_dead_state() ) {
11840  return true;
11841  }
11842 
11843  flvel -= force;
11844  if( thru ) {
11845  if( you != nullptr ) {
11846  if( you->in_vehicle ) {
11847  m.unboard_vehicle( you->pos() );
11848  }
11849  // If we're flinging the player around, make sure the map stays centered on them.
11850  if( is_u ) {
11851  update_map( pt.x, pt.y );
11852  } else {
11853  you->setpos( pt );
11854  }
11855  } else if( !creatures.creature_at( pt ) ) {
11856  // Dying monster doesn't always leave an empty tile (blob spawning etc.)
11857  // Just don't setpos if it happens - next iteration will do so
11858  // or the monster will stop a tile before the unpassable one
11859  c->setpos( pt );
11860  }
11861  } else {
11862  // Don't zero flvel - count this as slamming both the obstacle and the ground
11863  // although at lower velocity
11864  break;
11865  }
11866  range--;
11867  if( animate && ( seen || u.sees( *c ) ) ) {
11871  refresh_display();
11872  }
11873  }
11874 
11875  // Fall down to the ground - always on the last reached tile
11876  if( !m.has_flag( ter_furn_flag::TFLAG_SWIMMABLE, c->pos() ) ) {
11877  const trap &trap_under_creature = m.tr_at( c->pos() );
11878  // Didn't smash into a wall or a floor so only take the fall damage
11879  if( thru && trap_under_creature == tr_ledge ) {
11880  m.creature_on_trap( *c, false );
11881  } else {
11882  // Fall on ground
11883  int force = rng( flvel, flvel * 2 ) / 9;
11884  if( controlled ) {
11885  force = std::max( force / 2 - 5, 0 );
11886  }
11887  if( force > 0 ) {
11888  int dmg = c->impact( force, c->pos() );
11889  // TODO: Make landing damage the floor
11890  m.bash( c->pos(), dmg / 4, false, false, false );
11891  }
11892  // Always apply traps to creature i.e. bear traps, tele traps etc.
11893  m.creature_on_trap( *c, false );
11894  }
11895  } else {
11896  c->underwater = true;
11897 
11898  if( you != nullptr ) {
11899  water_affect_items( *you );
11900  }
11901 
11902  if( is_u ) {
11903  if( controlled ) {
11904  add_msg( _( "You dive into water." ) );
11905  } else {
11906  add_msg( m_warning, _( "You fall into water." ) );
11907  }
11908  }
11909  }
11910  return true;
11911 }
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:784
double calculate_by_enchantment(double modify, enchant_vals::mod value, bool round_output=false) const
Definition: character.cpp:7807
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:3067
Definition: effect.h:261
point update_map(Character &p, bool z_level_changed=false)
Definition: game.cpp:12615
void water_affect_items(Character &ch) const
Destroy / dissolve character items when in water.
Definition: game.cpp:11703
int bash_strength(const tripoint &p, bool allow_floor=false) const
Returns max_str of the furniture or terrain at p.
Definition: map.cpp:3276
void unboard_vehicle(const vpart_reference &, Character *passenger, bool dead_passenger=false)
Definition: map.cpp:1395
bool is_bashable(const tripoint &p, bool allow_floor=false) const
Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.
Definition: map.cpp:3240
bash_params bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:4292
void creature_on_trap(Creature &critter, bool may_avoid=true) const
Apply trap effects to the creature, similar to creature_in_field.
Definition: map.cpp:9887
int get_armor_type(const damage_type_id &dt, bodypart_id bp) const override
Definition: monster.cpp:2405
bool is_dead() const
Definition: monster.cpp:3580
void apply_damage(Creature *source, bodypart_id bp, int dam, bool bypass_med=false) override
Definition: monster.cpp:2169
std::optional< vpart_reference > obstacle_at_part() const
Definition: vehicle.cpp:2727
bool force
Definition: creature.h:241
static const damage_type_id damage_bash("bash")
static const json_character_flag json_flag_GRAB("GRAB")
void redraw_invalidated()
Redraw all invalidated windows without invalidating the top window.
Definition: ui_manager.cpp:509
int hp
Definition: mtype.h:413
Some traps aren't actually traps in the usual sense of the word.
Definition: trap.h:109
int y
Definition: point.h:133
int x
Definition: point.h:132

References _, add_msg(), tileray::advance(), monster::apply_damage(), map::bash(), map::bash_strength(), c, Character::calculate_by_enchantment(), Creature::check_dead_state(), creature_tracker::creature_at(), map::creature_on_trap(), damage_bash, debugmsg, tileray::dx(), tileray::dy(), force, monster::get_armor_type(), get_creature_tracker, map::has_flag(), mtype::hp, map::impassable(), Character::in_vehicle, inp_mngr, invalidate_main_ui_adaptor(), map::is_bashable(), monster::is_dead(), json_flag_GRAB, enchant_vals::KNOCKBACK_RESIST, m, m_warning, max(), optional_vpart_position::obstacle_at_part(), map::passable(), Creature::pos(), input_manager::pump_events(), ui_manager::redraw_invalidated(), refresh_display(), rng(), Character::sees(), Creature::setpos(), TFLAG_SWIMMABLE, map::tr_at(), tr_ledge, monster::type, u, map::unboard_vehicle(), update_map(), map::veh_at(), water_affect_items(), tripoint::x, x_in_y(), and tripoint::y.

Referenced by moving_vehicle_dismount().

◆ forced_door_closing() [1/2]

bool game::forced_door_closing ( const tripoint p,
const ter_id door_type,
int  bash_dmg 
)

Definition at line 5671 of file game.cpp.

5672 {
5673  // TODO: Z
5674  const int &x = p.x;
5675  const int &y = p.y;
5676  const std::string &door_name = door_type.obj().name();
5677  point kb( x, y ); // and when moving items out of the way
5678  const auto valid_location = [&]( const tripoint & p ) {
5679  return g->is_empty( p );
5680  };
5681  if( const std::optional<tripoint> pos = random_point( m.points_in_radius( p, 2 ),
5682  valid_location ) ) {
5683  kb.x = -pos->x + x + x;
5684  kb.y = -pos->y + y + y;
5685  }
5686  const tripoint kbp( kb, p.z );
5687  if( kbp == p ) {
5688  // can't pushback any creatures anywhere, that means the door can't close.
5689  return false;
5690  }
5691  const bool can_see = u.sees( tripoint( x, y, p.z ) );
5692  creature_tracker &creatures = get_creature_tracker();
5693  Character *npc_or_player = creatures.creature_at<Character>( tripoint( x, y, p.z ), false );
5694  if( npc_or_player != nullptr ) {
5695  if( bash_dmg <= 0 ) {
5696  return false;
5697  }
5698  if( npc_or_player->is_npc() && can_see ) {
5699  add_msg( _( "The %1$s hits the %2$s." ), door_name, npc_or_player->get_name() );
5700  } else if( npc_or_player->is_avatar() ) {
5701  add_msg( m_bad, _( "The %s hits you." ), door_name );
5702  }
5703  if( npc_or_player->activity ) {
5704  npc_or_player->cancel_activity();
5705  }
5706  // TODO: make the npc angry?
5707  npc_or_player->hitall( bash_dmg, 0, nullptr );
5708  knockback( kbp, p, std::max( 1, bash_dmg / 10 ), -1, 1 );
5709  // TODO: perhaps damage/destroy the gate
5710  // if the npc was really big?
5711  }
5712  if( monster *const mon_ptr = creatures.creature_at<monster>( p ) ) {
5713  monster &critter = *mon_ptr;
5714  if( bash_dmg <= 0 ) {
5715  return false;
5716  }
5717  if( can_see ) {
5718  add_msg( _( "The %1$s hits the %2$s." ), door_name, critter.name() );
5719  }
5720  if( critter.type->size <= creature_size::small ) {
5721  critter.die_in_explosion( nullptr );
5722  } else {
5723  critter.apply_damage( nullptr, bodypart_id( "torso" ), bash_dmg );
5724  critter.check_dead_state();
5725  }
5726  if( !critter.is_dead() && critter.type->size >= creature_size::huge ) {
5727  // big critters simply prevent the gate from closing
5728  // TODO: perhaps damage/destroy the gate
5729  // if the critter was really big?
5730  return false;
5731  }
5732  if( !critter.is_dead() ) {
5733  // Still alive? Move the critter away so the door can close
5734  knockback( kbp, p, std::max( 1, bash_dmg / 10 ), -1, 1 );
5735  if( creatures.creature_at( p ) ) {
5736  return false;
5737  }
5738  }
5739  }
5740  if( const optional_vpart_position vp = m.veh_at( p ) ) {
5741  if( bash_dmg <= 0 ) {
5742  return false;
5743  }
5744  vp->vehicle().damage( m, vp->part_index(), bash_dmg );
5745  if( m.veh_at( p ) ) {
5746  // Check again in case all parts at the door tile
5747  // have been destroyed, if there is still a vehicle
5748  // there, the door can not be closed
5749  return false;
5750  }
5751  }
5752  if( bash_dmg < 0 && !m.i_at( point( x, y ) ).empty() ) {
5753  return false;
5754  }
5755  if( bash_dmg == 0 ) {
5756  for( item &elem : m.i_at( point( x, y ) ) ) {
5757  if( elem.made_of( phase_id::LIQUID ) ) {
5758  // Liquids are OK, will be destroyed later
5759  continue;
5760  }
5761  if( elem.volume() < 250_ml ) {
5762  // Dito for small items, will be moved away
5763  continue;
5764  }
5765  // Everything else prevents the door from closing
5766  return false;
5767  }
5768  }
5769 
5770  m.ter_set( point( x, y ), door_type );
5771  if( m.has_flag( ter_furn_flag::TFLAG_NOITEM, point( x, y ) ) ) {
5772  map_stack items = m.i_at( point( x, y ) );
5773  for( map_stack::iterator it = items.begin(); it != items.end(); ) {
5774  if( it->made_of( phase_id::LIQUID ) ) {
5775  it = items.erase( it );
5776  continue;
5777  }
5778  const int glass_portion = it->made_of( material_glass );
5779  const float glass_fraction = glass_portion / static_cast<float>( it->type->mat_portion_total );
5780  if( glass_portion && rng_float( 0.0f, 1.0f ) < glass_fraction * 0.5f ) {
5781  if( can_see ) {
5782  add_msg( m_warning, _( "A %s shatters!" ), it->tname() );
5783  } else {
5784  add_msg( m_warning, _( "Something shatters!" ) );
5785  }
5786  it = items.erase( it );
5787  continue;
5788  }
5789  m.add_item_or_charges( kbp, *it );
5790  it = items.erase( it );
5791  }
5792  }
5793  return true;
5794 }
int hitall(int dam, int vary, Creature *source)
Harms all body parts for dam, with armor reduction.
Definition: character.cpp:8454
bool is_npc() const override
Definition: character.h:538
virtual bool is_avatar() const
Definition: creature.h:265
void knockback(const tripoint &s, const tripoint &t, int force, int stun, int dam_mult)
Definition: game.cpp:4853
iterator erase(const_iterator it) override
Definition: map.cpp:219
bool ter_set(const tripoint &p, const ter_id &new_terrain, bool avoid_creatures=false)
Definition: map.cpp:2226
void die_in_explosion(Creature *source)
Definition: monster.cpp:2189
static const material_id material_glass("glass")
std::optional< tripoint > random_point(const map &m, const std::function< bool(const tripoint &)> &predicate)
Same as other random_point with a range enclosing all valid points of the map.
double rng_float(double lo, double hi)
Definition: rng.cpp:27
std::string name() const
Definition: mapdata.cpp:563
creature_size size
Definition: mtype.h:407

References _, Character::activity, map::add_item_or_charges(), add_msg(), monster::apply_damage(), item_stack::begin(), Character::cancel_activity(), Creature::check_dead_state(), creature_tracker::creature_at(), monster::die_in_explosion(), item_stack::end(), map_stack::erase(), g, get_creature_tracker, Character::get_name(), map::has_flag(), Character::hitall(), huge, map::i_at(), Creature::is_avatar(), monster::is_dead(), Character::is_npc(), knockback(), LIQUID, m, m_bad, m_warning, material_glass, max(), map_data_common_t::name(), monster::name(), int_id< T >::obj(), point, map::points_in_radius(), math_opers::pos(), random_point(), rng_float(), Character::sees(), mtype::size, small, map::ter_set(), TFLAG_NOITEM, tripoint, monster::type, u, map::veh_at(), point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by forced_door_closing().

◆ forced_door_closing() [2/2]

bool game::forced_door_closing ( const tripoint_bub_ms p,
const ter_id door_type,
int  bash_dmg 
)

Definition at line 5796 of file game.cpp.

5797 {
5798  return forced_door_closing( p.raw(), door_type, bash_dmg );
5799 }
bool forced_door_closing(const tripoint &p, const ter_id &door_type, int bash_dmg)
Definition: game.cpp:5671

References forced_door_closing(), and coords::coord_point_mut< Point, Subpoint, InBounds >::raw().

◆ gametype()

special_game_type game::gametype ( ) const

Definition at line 838 of file game.cpp.

839 {
840  return gamemode ? gamemode->id() : special_game_type::NONE;
841 }

References gamemode, and NONE.

◆ get_characters_if()

std::vector< Character * > game::get_characters_if ( const std::function< bool(const Character &)> &  pred)

Definition at line 13142 of file game.cpp.

13144 {
13145  std::vector<Character *> result;
13146  avatar &a = get_avatar();
13147  if( pred( a ) ) {
13148  result.push_back( &a );
13149  }
13150  for( npc &guy : all_npcs() ) {
13151  if( pred( guy ) ) {
13152  result.push_back( &guy );
13153  }
13154  }
13155  return result;
13156 }

References a, all_npcs(), and get_avatar.

◆ get_creature_if()

Creature * game::get_creature_if ( const std::function< bool(const Creature &)> &  pred)

Returns a creature matching a predicate.

Only living (not dead) creatures are checked. Returns nullptr if no creature matches the predicate. There is no guarantee which creature is returned when several creatures match.

Definition at line 13238 of file game.cpp.

13239 {
13240  for( Creature &critter : all_creatures() ) {
13241  if( pred( critter ) ) {
13242  return &critter;
13243  }
13244  }
13245  return nullptr;
13246 }

References all_creatures().

◆ get_creatures_if()

std::vector< Creature * > game::get_creatures_if ( const std::function< bool(const Creature &)> &  pred)

Returns all creatures matching a predicate.

Only living ( not dead ) creatures are checked ( and returned ). Returned pointers are never null.

Definition at line 13130 of file game.cpp.

13132 {
13133  std::vector<Creature *> result;
13134  for( Creature &critter : all_creatures() ) {
13135  if( pred( critter ) ) {
13136  result.push_back( &critter );
13137  }
13138  }
13139  return result;
13140 }

References all_creatures().

Referenced by chat().

◆ get_cur_om()

overmap & game::get_cur_om ( ) const

The overmap which contains the center submap of the reality bubble.

Definition at line 13111 of file game.cpp.

13112 {
13113  // The player is located in the middle submap of the map.
13115  const tripoint_abs_om pos_om = project_to<coords::om>( sm );
13116  return overmap_buffer.get( pos_om.xy() );
13117 }
overmap & get(const point_abs_om &)
Uses overmap coordinates, that means x and y are directly compared with the position of the overmap.
constexpr int HALF_MAPSIZE
constexpr scale sm
Definition: coordinates.h:39

References overmapbuffer::get(), map::get_abs_sub(), HALF_MAPSIZE, m, overmap_buffer, coords::sm, tripoint, and coords::coord_point< Point, Origin, Scale, InBounds >::xy().

Referenced by start_game().

◆ get_dangerous_tile()

std::vector< std::string > game::get_dangerous_tile ( const tripoint dest_loc) const

Definition at line 10433 of file game.cpp.

10434 {
10435  if( u.is_blind() ) {
10436  return {}; // blinded players don't see dangerous tiles
10437  }
10438 
10439  std::vector<std::string> harmful_stuff;
10440  const field fields_here = m.field_at( u.pos() );
10441  const auto veh_here = m.veh_at( u.pos() ).part_with_feature( "BOARDABLE", true );
10442  const auto veh_dest = m.veh_at( dest_loc ).part_with_feature( "BOARDABLE", true );
10443  const bool veh_here_inside = veh_here && veh_here->is_inside();
10444  const bool veh_dest_inside = veh_dest && veh_dest->is_inside();
10445 
10446  for( const std::pair<const field_type_id, field_entry> &e : m.field_at( dest_loc ) ) {
10447  if( !u.is_dangerous_field( e.second ) ) {
10448  continue;
10449  }
10450 
10451  const bool has_field_here = fields_here.find_field( e.first ) != nullptr;
10452  const bool empty_effects = e.second.field_effects().empty();
10453 
10454  // if the field is dangerous but has no effects apparently this
10455  // means effects are hardcoded in map_field.cpp so we should...
10456  bool danger_dest = empty_effects; // ... warn if effects are empty
10457  bool danger_here = has_field_here && empty_effects;
10458  for( const field_effect &fe : e.second.field_effects() ) {
10459  if( !danger_dest ) {
10460  danger_dest = true;
10461  if( fe.immune_in_vehicle && veh_dest ) { // NOLINT(bugprone-branch-clone)
10462  danger_dest = false;
10463  } else if( fe.immune_inside_vehicle && veh_dest_inside ) {
10464  danger_dest = false;
10465  } else if( fe.immune_outside_vehicle && !veh_dest_inside ) {
10466  danger_dest = false;
10467  } else if( u.is_immune_effect( fe.id ) || u.check_immunity_data( fe.immunity_data ) ) {
10468  danger_dest = false;
10469  }
10470  }
10471  if( has_field_here && !danger_here ) {
10472  danger_here = true;
10473  if( fe.immune_in_vehicle && veh_here ) { // NOLINT(bugprone-branch-clone)
10474  danger_here = false;
10475  } else if( fe.immune_inside_vehicle && veh_here_inside ) {
10476  danger_here = false;
10477  } else if( fe.immune_outside_vehicle && !veh_here_inside ) {
10478  danger_here = false;
10479  } else if( u.is_immune_effect( fe.id ) || u.check_immunity_data( fe.immunity_data ) ) {
10480  danger_here = false;
10481  }
10482  }
10483  }
10484 
10485  // don't warn if already in a field of the same type
10486  if( !danger_dest || danger_here ) {
10487  continue;
10488  }
10489 
10490  harmful_stuff.push_back( e.second.name() );
10491  }
10492 
10493  const trap &tr = m.tr_at( dest_loc );
10494  // HACK: Hack for now, later ledge should stop being a trap
10495  if( tr == tr_ledge ) {
10496  if( !veh_dest && !u.has_effect_with_flag( json_flag_LEVITATION ) ) {
10497  harmful_stuff.emplace_back( tr.name() );
10498  }
10499  } else if( tr.can_see( dest_loc, u ) && !tr.is_benign() && !veh_dest ) {
10500  harmful_stuff.emplace_back( tr.name() );
10501  }
10502 
10503  static const std::set< bodypart_str_id > sharp_bps = {
10508  };
10509 
10510  const auto sharp_bp_check = [this]( bodypart_id bp ) {
10511  return u.immune_to( bp, { damage_cut, 10 } );
10512  };
10513 
10514  if( m.has_flag( ter_furn_flag::TFLAG_ROUGH, dest_loc ) &&
10516  !veh_dest &&
10517  ( u.get_armor_type( damage_bash, bodypart_id( "foot_l" ) ) < 5 ||
10518  u.get_armor_type( damage_bash, bodypart_id( "foot_r" ) ) < 5 ) ) { // NOLINT(bugprone-branch-clone)
10519  harmful_stuff.emplace_back( m.name( dest_loc ) );
10520  } else if( m.has_flag( ter_furn_flag::TFLAG_SHARP, dest_loc ) &&
10522  !( u.in_vehicle || m.veh_at( dest_loc ) ) &&
10523  u.dex_cur < 78 &&
10524  !( u.is_mounted() &&
10525  u.mounted_creature->get_armor_type( damage_cut, bodypart_id( "torso" ) ) >= 10 ) &&
10526  !std::all_of( sharp_bps.begin(), sharp_bps.end(), sharp_bp_check ) ) {
10527  harmful_stuff.emplace_back( m.name( dest_loc ) );
10528  }
10529 
10530  return harmful_stuff;
10531 }
const bodypart_str_id body_part_foot_r("foot_r")
const bodypart_str_id body_part_hand_r("hand_r")
const bodypart_str_id body_part_leg_l("leg_l")
const bodypart_str_id body_part_arm_l("arm_l")
const bodypart_str_id body_part_torso("torso")
const bodypart_str_id body_part_arm_r("arm_r")
const bodypart_str_id body_part_leg_r("leg_r")
const bodypart_str_id body_part_mouth("mouth")
const bodypart_str_id body_part_head("head")
const bodypart_str_id body_part_hand_l("hand_l")
const bodypart_str_id body_part_foot_l("foot_l")
const bodypart_str_id body_part_eyes("eyes")
bool check_immunity_data(const field_immunity_data &ft) const override
Definition: character.cpp:5786
int dex_cur
Definition: character.h:578
bool immune_to(const bodypart_id &bp, damage_unit dam) const
Check if a given body part is immune to a given damage type.
int get_armor_type(const damage_type_id &dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
bool is_immune_effect(const efftype_id &) const override
Returns true if the player is immune to this kind of effect.
Definition: character.cpp:5882
bool has_effect_with_flag(const flag_id &flag, const bodypart_id &bp) const
Check if creature has any effect with the given flag.
Definition: creature.cpp:1792
bool is_dangerous_field(const field_entry &entry) const
Returns true if the given field entry is dangerous to us.
Definition: creature.cpp:346
std::vector< field_effect > field_effects() const
Definition: field.cpp:266
A variable sized collection of field entries on a given map square.
Definition: field.h:107
field_entry * find_field(const field_type_id &field_type_to_find, bool alive_only=true)
Returns a field entry corresponding to the field_type_id parameter passed in.
Definition: field.cpp:122
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:6379
bodypart_id bp
Definition: creature.h:238
static const flag_id json_flag_LEVITATION("LEVITATION")
static const damage_type_id damage_cut("cut")
std::string name() const
Definition: trap.cpp:228
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:320
bool is_benign() const
If true, this is not really a trap and there won't be any safety queries before stepping onto it (e....
Definition: trap.h:221

References body_part_arm_l, body_part_arm_r, body_part_eyes, body_part_foot_l, body_part_foot_r, body_part_hand_l, body_part_hand_r, body_part_head, body_part_leg_l, body_part_leg_r, body_part_mouth, body_part_torso, bp, trap::can_see(), Character::check_immunity_data(), damage_bash, damage_cut, Character::dex_cur, map::field_at(), field::find_field(), Character::get_armor_type(), Creature::has_effect_with_flag(), map::has_flag(), Character::immune_to(), Character::in_vehicle, trap::is_benign(), Character::is_blind(), Creature::is_dangerous_field(), Character::is_immune_effect(), Character::is_mounted(), json_flag_LEVITATION, m, Character::mounted_creature, trap::name(), map::name(), optional_vpart_position::part_with_feature(), Creature::pos(), TFLAG_ROUGH, TFLAG_SHARP, map::tr_at(), tr_ledge, u, and map::veh_at().

Referenced by grabbed_furn_move(), is_dangerous_tile(), prompt_dangerous_tile(), and walk_move().

◆ get_fishable_locations()

std::unordered_set< tripoint > game::get_fishable_locations ( int  distance,
const tripoint fish_pos 
)

Get the contiguous fishable locations starting at fish_pos, out to the specified distance.

Parameters
distanceDistance around the fish_pos to examine for contiguous fishable locations.
fish_posThe location being fished.
Returns
A set of locations representing the valid contiguous fishable locations.

Definition at line 4521 of file game.cpp.

4522 {
4523  // We're going to get the contiguous fishable terrain starting at
4524  // the provided fishing location (e.g. where a line was cast or a fish
4525  // trap was set), and then check whether or not fishable monsters are
4526  // actually in those locations. This will help us ensure that we're
4527  // getting our fish from the location that we're ACTUALLY fishing,
4528  // rather than just somewhere in the vicinity.
4529 
4530  std::unordered_set<tripoint> visited;
4531 
4532  const tripoint fishing_boundary_min( fish_pos + point( -distance, -distance ) );
4533  const tripoint fishing_boundary_max( fish_pos + point( distance, distance ) );
4534 
4535  const inclusive_cuboid<tripoint> fishing_boundaries(
4536  fishing_boundary_min, fishing_boundary_max );
4537 
4538  const auto get_fishable_terrain = [&]( tripoint starting_point,
4539  std::unordered_set<tripoint> &fishable_terrain ) {
4540  std::queue<tripoint> to_check;
4541  to_check.push( starting_point );
4542  while( !to_check.empty() ) {
4543  const tripoint current_point = to_check.front();
4544  to_check.pop();
4545 
4546  // We've been here before, so bail.
4547  if( visited.find( current_point ) != visited.end() ) {
4548  continue;
4549  }
4550 
4551  // This point is out of bounds, so bail.
4552  if( !fishing_boundaries.contains( current_point ) ) {
4553  continue;
4554  }
4555 
4556  // Mark this point as visited.
4557  visited.emplace( current_point );
4558 
4559  if( m.has_flag( ter_furn_flag::TFLAG_FISHABLE, current_point ) ) {
4560  fishable_terrain.emplace( current_point );
4561  to_check.push( current_point + point_south );
4562  to_check.push( current_point + point_north );
4563  to_check.push( current_point + point_east );
4564  to_check.push( current_point + point_west );
4565  }
4566  }
4567  };
4568 
4569  // Starting at the provided location, get our fishable terrain
4570  // and populate a set with those locations which we'll then use
4571  // to determine if any fishable monsters are in those locations.
4572  std::unordered_set<tripoint> fishable_points;
4573  get_fishable_terrain( fish_pos, fishable_points );
4574 
4575  return fishable_points;
4576 }
constexpr point point_west
Definition: point.h:259
constexpr point point_south
Definition: point.h:257
constexpr point point_north
Definition: point.h:253
constexpr point point_east
Definition: point.h:255

References inclusive_cuboid< Tripoint, >::contains(), map::has_flag(), m, point, point_east, point_north, point_south, point_west, and TFLAG_FISHABLE.

◆ get_fishable_monsters()

std::vector< monster * > game::get_fishable_monsters ( std::unordered_set< tripoint > &  fishable_locations)

Get the fishable monsters within the provided fishable locations.

Parameters
fishable_locationsA set of locations which are valid fishable terrain. Any fishable monsters are filtered by this collection to determine those which can actually be caught.
Returns
Fishable monsters within the specified fishable terrain.

Definition at line 4578 of file game.cpp.

4580 {
4581  std::vector<monster *> unique_fish;
4582  for( monster &critter : all_monsters() ) {
4583  // If it is fishable...
4584  if( critter.has_flag( mon_flag_FISHABLE ) ) {
4585  const tripoint critter_pos = critter.pos();
4586  // ...and it is in a fishable location.
4587  if( fishable_locations.find( critter_pos ) != fishable_locations.end() ) {
4588  unique_fish.push_back( &critter );
4589  }
4590  }
4591  }
4592 
4593  return unique_fish;
4594 }
mon_flag_id mon_flag_FISHABLE
Definition: mtype.cpp:85

References all_monsters(), and mon_flag_FISHABLE.

◆ get_follower_list()

std::set< character_id > game::get_follower_list ( )

Get set of followers.

Definition at line 1817 of file game.cpp.

1818 {
1819  return follower_ids;
1820 }

References follower_ids.

◆ get_kill_tracker()

const kill_tracker & game::get_kill_tracker ( ) const

Definition at line 1272 of file game.cpp.

1273 {
1274  return *kill_tracker_ptr;
1275 }

References kill_tracker_ptr.

Referenced by death_screen().

◆ get_moves_since_last_save()

int game::get_moves_since_last_save ( ) const

Definition at line 8224 of file game.cpp.

8225 {
8226  return moves_since_last_save;
8227 }
int moves_since_last_save
Definition: game.h:1174

References moves_since_last_save.

◆ get_npcs_if()

std::vector< npc * > game::get_npcs_if ( const std::function< bool(const npc &)> &  pred)

Definition at line 13158 of file game.cpp.

13159 {
13160  std::vector<npc *> result;
13161  for( npc &guy : all_npcs() ) {
13162  if( pred( guy ) ) {
13163  result.push_back( &guy );
13164  }
13165  }
13166  return result;
13167 }

References all_npcs().

Referenced by allies(), chat(), and validate_npc_followers().

◆ get_player_input()

input_context game::get_player_input ( std::string &  action)
private

Definition at line 236 of file handle_action.cpp.

237 {
238  input_context ctxt;
239  if( uquit == QUIT_WATCH ) {
240  ctxt = input_context( "DEFAULTMODE", keyboard_mode::keycode );
241  ctxt.set_iso( true );
242  // The list of allowed actions in death-cam mode in game::handle_action
243  // *INDENT-OFF*
244  for( const action_id id : {
255  ACTION_LOOK,
257  } ) {
258  ctxt.register_action( action_ident( id ) );
259  }
260  // *INDENT-ON*
261  ctxt.register_action( "QUIT", to_translation( "Accept your fate" ) );
262  } else {
264  }
265 
268  const level_cache &map_cache = m.get_cache_ref( u.posz() );
269  const auto &visibility_cache = map_cache.visibility_cache;
270 #if defined(TILES)
271  // Mark cata_tiles draw caches as dirty
272  tilecontext->set_draw_cache_dirty();
273 #endif
274 
275  user_turn current_turn;
276 
277  if( get_option<bool>( "ANIMATIONS" ) ) {
278  const int TOTAL_VIEW = MAX_VIEW_DISTANCE * 2 + 1;
279  point iStart( ( TERRAIN_WINDOW_WIDTH > TOTAL_VIEW ) ? ( TERRAIN_WINDOW_WIDTH - TOTAL_VIEW ) / 2 : 0,
280  ( TERRAIN_WINDOW_HEIGHT > TOTAL_VIEW ) ? ( TERRAIN_WINDOW_HEIGHT - TOTAL_VIEW ) / 2 :
281  0 );
282  point iEnd( ( TERRAIN_WINDOW_WIDTH > TOTAL_VIEW ) ? TERRAIN_WINDOW_WIDTH -
283  ( TERRAIN_WINDOW_WIDTH - TOTAL_VIEW ) /
284  2 :
286  ( TERRAIN_WINDOW_HEIGHT - TOTAL_VIEW ) /
287  2 : TERRAIN_WINDOW_HEIGHT );
288 
289  if( fullscreen ) {
290  iStart.x = 0;
291  iStart.y = 0;
292  iEnd.x = TERMX;
293  iEnd.y = TERMY;
294  }
295 
296  //x% of the Viewport, only shown on visible areas
298  point offset( u.view_offset.xy() + point( -getmaxx( w_terrain ) / 2 + u.posx(),
299  -getmaxy( w_terrain ) / 2 + u.posy() ) );
300 
301 #if defined(TILES)
302  if( g->is_tileset_isometric() ) {
303  iStart.x = 0;
304  iStart.y = 0;
305  iEnd.x = MAPSIZE_X;
306  iEnd.y = MAPSIZE_Y;
307  offset.x = 0;
308  offset.y = 0;
309  }
310 #endif //TILES
311 
312  // TODO: Move the weather calculations out of here.
313  const bool bWeatherEffect = weather_info.symbol != NULL_UNICODE;
314  const int dropCount = static_cast<int>( iEnd.x * iEnd.y * weather_info.factor );
315 
316  weather_printable wPrint;
317  wPrint.colGlyph = weather_info.color;
318  wPrint.cGlyph = weather_info.symbol;
319  wPrint.wtype = weather.weather_id;
320  wPrint.vdrops.clear();
321 
322  ctxt.set_timeout( 125 );
323 
325  make_shared_fast<game::draw_callback_t>( [&]() {
326  draw_weather( wPrint );
327 
328  if( uquit != QUIT_WATCH ) {
329  draw_sct();
330  }
331  } );
332  add_draw_callback( animation_cb );
333 
334  creature_tracker &creatures = get_creature_tracker();
335  do {
336  if( bWeatherEffect && get_option<bool>( "ANIMATION_RAIN" ) ) {
337  /*
338  Location to add rain drop animation bits! Since it refreshes w_terrain it can be added to the animation section easily
339  Get tile information from above's weather information:
340  WEATHER_DRIZZLE | WEATHER_LIGHT_DRIZZLE | WEATHER_RAINY | WEATHER_RAINSTORM | WEATHER_THUNDER | WEATHER_LIGHTNING = "weather_rain_drop"
341  WEATHER_FLURRIES | WEATHER_SNOW | WEATHER_SNOWSTORM = "weather_snowflake"
342  */
344 
345  wPrint.vdrops.clear();
346 
347  for( int i = 0; i < dropCount; i++ ) {
348  const point iRand( rng( iStart.x, iEnd.x - 1 ), rng( iStart.y, iEnd.y - 1 ) );
349  const point map( iRand + offset );
350 
351  const tripoint mapp( map, u.posz() );
352 
353  if( m.inbounds( mapp ) && m.is_outside( mapp ) &&
354  m.get_visibility( visibility_cache[mapp.x][mapp.y], cache ) ==
356  !creatures.creature_at( mapp, true ) ) {
357  // Suppress if a critter is there
358  wPrint.vdrops.emplace_back( iRand.x, iRand.y );
359  }
360  }
361  }
362  // don't bother calculating SCT if we won't show it
363  if( uquit != QUIT_WATCH && get_option<bool>( "ANIMATION_SCT" ) && !SCT.vSCT.empty() ) {
365 
367 
368  //Check for creatures on all drawing positions and offset if necessary
369  for( auto iter = SCT.vSCT.rbegin(); iter != SCT.vSCT.rend(); ++iter ) {
370  const direction oCurDir = iter->getDirection();
371  const int width = utf8_width( iter->getText() );
372  for( int i = 0; i < width; ++i ) {
373  tripoint tmp( iter->getPosX() + i, iter->getPosY(), get_map().get_abs_sub().z() );
374  const Creature *critter = creatures.creature_at( tmp, true );
375 
376  if( critter != nullptr && u.sees( *critter ) ) {
377  i = -1;
378  int iPos = iter->getStep() + iter->getStepOffset();
379  for( auto iter2 = iter; iter2 != SCT.vSCT.rend(); ++iter2 ) {
380  if( iter2->getDirection() == oCurDir &&
381  iter2->getStep() + iter2->getStepOffset() <= iPos ) {
382  if( iter2->getType() == "hp" ) {
383  iter2->advanceStepOffset();
384  }
385 
386  iter2->advanceStepOffset();
387  iPos = iter2->getStep() + iter2->getStepOffset();
388  }
389  }
390  }
391  }
392  }
393  }
394 
395  if( pixel_minimap_option ) {
396  // TODO: more granular control to only redraw pixel minimap
398  }
399 
400  std::unique_ptr<static_popup> deathcam_msg_popup;
401  if( uquit == QUIT_WATCH ) {
402  deathcam_msg_popup = std::make_unique<static_popup>();
403  deathcam_msg_popup
404  ->wait_message( c_red, _( "Press %s to accept your fate…" ), ctxt.get_desc( "QUIT" ) )
405  .on_top( true );
406  }
407 
408  // Remove asynchronous animations after animation delay if no input
409  if( current_turn.async_anim_timeout() ) {
410  g->void_async_anim_curses();
411 #if defined(TILES)
412  tilecontext->void_async_anim();
413 #else
414  // Curses does not redraw itself so do it here
415  g->invalidate_main_ui_adaptor();
416 #endif
417  }
418 
419  if( g->has_blink_curses() && current_turn.blink_timeout() ) {
420  // Toggle blink phase and redraw
421  g->blink_active_phase = !g->blink_active_phase;
422  g->invalidate_main_ui_adaptor();
423  }
424 
426  } while( handle_mouseview( ctxt, action ) && uquit != QUIT_WATCH
427  && ( action != "TIMEOUT" || !current_turn.has_timeout_elapsed() ) );
428  ctxt.reset_timeout();
429  } else {
430  ctxt.set_timeout( 125 );
431  while( handle_mouseview( ctxt, action ) ) {
432  if( action == "TIMEOUT" && current_turn.has_timeout_elapsed() ) {
433  break;
434  }
435  }
436  ctxt.reset_timeout();
437  }
438 
439  return ctxt;
440 }
std::string action_ident(action_id act)
Lookup a unique string identifier for a given action ID.
Definition: action.cpp:116
action_id
Enumerates all discrete actions that can be performed by player.
Definition: action.h:21
@ ACTION_CENTER
Center the viewport on character.
Definition: action.h:82
@ ACTION_SHIFT_SW
Move viewport south-west.
Definition: action.h:94
@ ACTION_SHIFT_NW
Move viewport north-west.
Definition: action.h:98
@ ACTION_SHIFT_E
Move viewport east.
Definition: action.h:88
@ ACTION_TOGGLE_MAP_MEMORY
Toggle memorized tiles being shown.
Definition: action.h:80
@ ACTION_SHIFT_S
Move viewport south.
Definition: action.h:92
@ ACTION_SHIFT_SE
Move viewport south-east.
Definition: action.h:90
@ ACTION_LOOK
Toggle look mode.
Definition: action.h:129
@ ACTION_SHIFT_NE
Move viewport north-east.
Definition: action.h:86
@ ACTION_SHIFT_W
Move viewport west.
Definition: action.h:96
@ ACTION_SHIFT_N
Move viewport north.
Definition: action.h:84
bool pixel_minimap_option
constexpr int NULL_UNICODE
Definition: catacharset.h:13
void add_draw_callback(const shared_ptr_fast< draw_callback_t > &cb)
Definition: game.cpp:3833
void draw_sct() const
Definition: animation.cpp:824
void draw_weather(const weather_printable &wPrint) const
Definition: animation.cpp:782
bool handle_mouseview(input_context &ctxt, std::string &action)
Definition: game.cpp:2355
weather_manager weather
Definition: game.h:1146
bool fullscreen
Definition: game.h:1136
void set_timeout(int val)
Sets input polling timeout as appropriate for the current interface system.
std::string get_desc(const std::string &action_descriptor, unsigned int max_limit=0, const input_event_filter &evt_filter=allow_all_keys) const
Get a description text for the key/other input method associated with the given action.
void register_action(const std::string &action_descriptor)
Register an action with this input context.
void set_iso(bool mode=true)
const level_cache & get_cache_ref(int zlev) const
Definition: map.h:2335
const visibility_variables & get_visibility_variables_cache() const
Definition: map.cpp:6879
std::vector< cSCT > vSCT
Definition: output.h:1120
void advanceAllSteps()
Definition: output.cpp:3090
bool has_timeout_elapsed()
bool blink_timeout()
bool async_anim_timeout()
weather_type_id weather_id
Definition: weather.h:209
input_context get_default_mode_input_context()
Definition: game.cpp:2455
@ QUIT_WATCH
Definition: game.h:58
constexpr int MAX_VIEW_DISTANCE
direction
Definition: line.h:42
scrollingcombattext SCT
Definition: output.cpp:67
cata::mdarray< lit_level, point_bub_ms > visibility_cache
Definition: level_cache.h:75
Weather animation class.
Definition: weather_type.h:65
Weather drawing tracking.
Definition: weather.h:98
nc_color colGlyph
Glyph to draw this animation frame.
Definition: weather.h:104
std::vector< std::pair< int, int > > vdrops
Color to draw glyph this animation frame.
Definition: weather.h:102
weather_type_id wtype
< Weather type in use.
Definition: weather.h:100
uint32_t cGlyph
Definition: weather.h:106
weather_animation_t weather_animation
Definition: weather_type.h:107
translation to_translation(const std::string &raw)
Shorthands for translation::to_translation.

References _, action, ACTION_CENTER, action_ident(), ACTION_KEYBINDINGS, ACTION_LOOK, ACTION_SHIFT_E, ACTION_SHIFT_N, ACTION_SHIFT_NE, ACTION_SHIFT_NW, ACTION_SHIFT_S, ACTION_SHIFT_SE, ACTION_SHIFT_SW, ACTION_SHIFT_W, ACTION_TOGGLE_MAP_MEMORY, add_draw_callback(), scrollingcombattext::advanceAllSteps(), user_turn::async_anim_timeout(), user_turn::blink_timeout(), c_red, weather_printable::cGlyph, CLEAR, weather_printable::colGlyph, weather_animation_t::color, creature_tracker::creature_at(), draw_sct(), draw_weather(), weather_animation_t::factor, fullscreen, g, map::get_cache_ref(), get_creature_tracker, get_default_mode_input_context(), input_context::get_desc(), get_map, map::get_visibility(), map::get_visibility_variables_cache(), catacurses::getmaxx(), catacurses::getmaxy(), handle_mouseview(), user_turn::has_timeout_elapsed(), map::inbounds(), invalidate_main_ui_adaptor(), map::is_outside(), keycode, m, map, MAPSIZE_X, MAPSIZE_Y, MAX_VIEW_DISTANCE, NULL_UNICODE, pixel_minimap_option, Creature::posx(), Creature::posy(), Creature::posz(), QUIT_WATCH, ui_manager::redraw_invalidated(), input_context::register_action(), input_context::reset_timeout(), rng(), SCT, Character::sees(), input_context::set_iso(), input_context::set_timeout(), weather_animation_t::symbol, TERMX, TERMY, TERRAIN_WINDOW_HEIGHT, TERRAIN_WINDOW_WIDTH, to_translation(), u, map::update_visibility_cache(), uquit, utf8_width(), weather_printable::vdrops, Character::view_offset, level_cache::visibility_cache, scrollingcombattext::vSCT, w_terrain, weather, weather_type::weather_animation, weather_manager::weather_id, weather_printable::wtype, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by handle_action().

◆ get_seed()

unsigned int game::get_seed ( ) const

Definition at line 1592 of file game.cpp.

1593 {
1594  return seed;
1595 }
unsigned int seed
Seed for all the random numbers that should have consistent randomness (weather).
Definition: game.h:1200

References seed.

◆ get_unique_npc_location()

point_abs_om game::get_unique_npc_location ( const std::string &  id)

Definition at line 3447 of file game.cpp.

3448 {
3449  if( unique_npc_exists( id ) ) {
3450  return unique_npcs[id];
3451  } else {
3452  debugmsg( "Tried to find npc %s which doesn't exist.", id );
3453  return point_abs_om();
3454  }
3455 }
bool unique_npc_exists(const std::string &id)
Definition: game.cpp:3457
std::unordered_map< std::string, point_abs_om > unique_npcs
Definition: game.h:1088
coords::coord_point< point, coords::origin::abs, coords::om > point_abs_om
Definition: coordinates.h:709
const std::string id
Definition: basecamp.h:105

References debugmsg, base_camps::id, unique_npc_exists(), and unique_npcs.

◆ get_user_action_counter()

int game::get_user_action_counter ( ) const

Definition at line 8229 of file game.cpp.

8230 {
8231  return user_action_counter;
8232 }
int user_action_counter
Definition: game.h:1193

References user_action_counter.

◆ get_veh_dir_indicator_location()

std::optional< tripoint > game::get_veh_dir_indicator_location ( bool  next) const

Returns the location where the indicator should go relative to the reality bubble, or nothing to indicate no indicator should be drawn.

Based on the vehicle the player is driving, if any.

Parameters
nextIf true, bases it on the vehicle the vehicle will turn to next turn, instead of the one it is currently facing.

Definition at line 4167 of file game.cpp.

4168 {
4169  if( !get_option<bool>( "VEHICLE_DIR_INDICATOR" ) ) {
4170  return std::nullopt;
4171  }
4172  const optional_vpart_position vp = m.veh_at( u.pos() );
4173  if( !vp ) {
4174  return std::nullopt;
4175  }
4176  vehicle *const veh = &vp->vehicle();
4177  rl_vec2d face = next ? veh->dir_vec() : veh->face_vec();
4178  float r = 10.0f;
4179  return tripoint( static_cast<int>( r * face.x ), static_cast<int>( r * face.y ), u.pos().z );
4180 }
rl_vec2d dir_vec() const

References vehicle::dir_vec(), vehicle::face_vec(), m, Creature::pos(), tripoint, u, map::veh_at(), rl_vec2d::x, rl_vec2d::y, and tripoint::z.

Referenced by draw_veh_dir_indicator().

◆ get_zoom()

int game::get_zoom ( ) const

Definition at line 8215 of file game.cpp.

8216 {
8217 #if defined(TILES)
8218  return tileset_zoom;
8219 #else
8220  return DEFAULT_TILESET_ZOOM;
8221 #endif
8222 }

References DEFAULT_TILESET_ZOOM, and tileset_zoom.

Referenced by look_around().

◆ grabbed_furn_move()

bool game::grabbed_furn_move ( const tripoint dp)
Strength determines ability to drag furniture

Definition at line 11441 of file game.cpp.

11442 {
11443  // Furniture: pull, push, or standing still and nudging object around.
11444  // Can push furniture out of reach.
11445  tripoint fpos = u.pos() + u.grab_point;
11446  // supposed position of grabbed furniture
11447  if( !m.has_furn( fpos ) ) {
11448  // Where did it go? We're grabbing thin air so reset.
11449  add_msg( m_info, _( "No furniture at grabbed point." ) );
11451  return false;
11452  }
11453 
11454  int ramp_offset = 0;
11455  // Furniture could be on a ramp at different time than player so adjust for that.
11456  if( m.has_flag( ter_furn_flag::TFLAG_RAMP_UP, fpos + tripoint( dp.xy(), 0 ) ) ) {
11457  ramp_offset = 1;
11458  } else if( m.has_flag( ter_furn_flag::TFLAG_RAMP_DOWN, fpos + tripoint( dp.xy(), 0 ) ) ) {
11459  ramp_offset = -1;
11460  }
11461 
11462  const bool pushing_furniture = dp.xy() == u.grab_point.xy();
11463  const bool pulling_furniture = dp.xy() == -u.grab_point.xy();
11464  const bool shifting_furniture = !pushing_furniture && !pulling_furniture;
11465 
11466  // Intended destination of furniture.
11467  const tripoint fdest = fpos + tripoint( dp.xy(), ramp_offset );
11468 
11469  // Unfortunately, game::is_empty fails for tiles we're standing on,
11470  // which will forbid pulling, so:
11471  const bool canmove = can_move_furniture( fdest, dp );
11472  // @TODO: it should be possible to move over invisible traps. This should probably
11473  // trigger the trap.
11474  // The current check (no move if trap) allows a player to detect invisible traps by
11475  // attempting to move stuff onto it.
11476 
11477  const furn_t furntype = m.furn( fpos ).obj();
11478  const int src_items = m.i_at( fpos ).size();
11479  const int dst_items = m.i_at( fdest ).size();
11480 
11481  const bool only_liquid_items = std::all_of( m.i_at( fdest ).begin(), m.i_at( fdest ).end(),
11482  [&]( item & liquid_item ) {
11483  return liquid_item.made_of_from_type( phase_id::LIQUID );
11484  } );
11485 
11486  const bool dst_item_ok = !m.has_flag( ter_furn_flag::TFLAG_NOITEM, fdest ) &&
11489 
11490  const bool src_item_ok = m.furn( fpos ).obj().has_flag( ter_furn_flag::TFLAG_CONTAINER ) ||
11493 
11494  const int fire_intensity = m.get_field_intensity( fpos, fd_fire );
11495  time_duration fire_age = m.get_field_age( fpos, fd_fire );
11496 
11497  int str_req = furntype.move_str_req;
11498  // Factor in weight of items contained in the furniture.
11499  units::mass furniture_contents_weight = 0_gram;
11500  for( item &contained_item : m.i_at( fpos ) ) {
11501  furniture_contents_weight += contained_item.weight();
11502  }
11503  str_req += furniture_contents_weight / 4_kilogram;
11504  int str = u.get_arm_str();
11505 
11506  if( !canmove ) {
11507  // TODO: What is something?
11508  add_msg( _( "The %s collides with something." ), furntype.name() );
11509  return true;
11510  } else if( str_req > str && u.get_perceived_pain() > 40 &&
11513  add_msg( m_bad, _( "You are in too much pain to try moving the heavy %s!" ),
11514  furntype.name() );
11515  return true;
11516 
11517  } else if( str_req > str && u.get_perceived_pain() > 50 &&
11519  add_msg( m_bad,
11520  _( "Even with your appetite for pain, you are in too much pain to try moving the heavy %s!" ),
11521  furntype.name() );
11522  return true;
11523 
11524  ///\EFFECT_STR determines ability to drag furniture
11525  } else if( str_req > str &&
11526  one_in( std::max( 20 - str_req - str, 2 ) ) ) {
11527  add_msg( m_bad, _( "You strain yourself trying to move the heavy %s!" ),
11528  furntype.name() );
11529  u.mod_pain( 1 ); // Hurt ourselves.
11530  return true; // furniture and or obstacle wins.
11531  } else if( !src_item_ok && !only_liquid_items && dst_items > 0 ) {
11532  add_msg( _( "There's stuff in the way." ) );
11533  return true;
11534  }
11535 
11536  // Additional penalty if we can't comfortably move it.
11537  if( str_req > str ) {
11538  int move_penalty = std::pow( str_req, 2.0 ) + 100.0;
11539  if( move_penalty <= 1000 ) {
11540  if( str >= str_req - 3 ) {
11541  add_msg( m_bad, _( "The %s is really heavy!" ), furntype.name() );
11542  if( one_in( 3 ) ) {
11543  add_msg( m_bad, _( "You fail to move the %s." ), furntype.name() );
11544  return true;
11545  }
11546  } else {
11547  add_msg( m_bad, _( "The %s is too heavy for you to budge." ), furntype.name() );
11548  return true;
11549  }
11550  }
11551  if( move_penalty > 500 ) {
11552  add_msg( _( "Moving the heavy %s is taking a lot of time!" ),
11553  furntype.name() );
11554  } else if( move_penalty > 200 ) {
11555  if( one_in( 3 ) ) { // Nag only occasionally.
11556  add_msg( _( "It takes some time to move the heavy %s." ),
11557  furntype.name() );
11558  }
11559  }
11560  }
11562  _( "a scraping noise." ), true, "misc", "scraping" );
11563 
11564  // Actually move the furniture.
11565  m.furn_set( fdest, m.furn( fpos ) );
11566  m.furn_set( fpos, furn_str_id::NULL_ID(), true );
11567 
11568  if( fire_intensity == 1 && !pulling_furniture ) {
11569  m.remove_field( fpos, fd_fire );
11570  m.set_field_intensity( fdest, fd_fire, fire_intensity );
11571  m.set_field_age( fdest, fd_fire, fire_age );
11572  }
11573 
11574  // Is there is only liquids on the ground, remove them after moving furniture.
11575  if( dst_items > 0 && only_liquid_items ) {
11576  m.i_clear( fdest );
11577  }
11578 
11579  if( src_items > 0 ) { // Move the stuff inside.
11580  if( dst_item_ok && src_item_ok ) {
11581  // Assume contents of both cells are legal, so we can just swap contents.
11582  std::list<item> temp;
11583  std::move( m.i_at( fpos ).begin(), m.i_at( fpos ).end(),
11584  std::back_inserter( temp ) );
11585  m.i_clear( fpos );
11586  for( auto item_iter = m.i_at( fdest ).begin();
11587  item_iter != m.i_at( fdest ).end(); ++item_iter ) {
11588  m.i_at( fpos ).insert( *item_iter );
11589  }
11590  m.i_clear( fdest );
11591  for( item &cur_item : temp ) {
11592  m.i_at( fdest ).insert( cur_item );
11593  }
11594  } else {
11595  add_msg( _( "Stuff spills from the %s!" ), furntype.name() );
11596  }
11597  }
11598 
11599  if( !m.has_floor_or_water( fdest ) && !m.has_flag( ter_furn_flag::TFLAG_FLAT, fdest ) ) {
11600  std::string danger_tile = enumerate_as_string( get_dangerous_tile( fdest ) );
11601  add_msg( _( "You let go of the %1$s as it falls down the %2$s." ), furntype.name(), danger_tile );
11603  m.drop_furniture( fdest );
11604  return true;
11605  }
11606 
11607  u.grab_point.z += ramp_offset;
11608 
11609  if( shifting_furniture ) {
11610  // We didn't move
11611  tripoint d_sum = u.grab_point + dp;
11612  if( std::abs( d_sum.x ) < 2 && std::abs( d_sum.y ) < 2 ) {
11613  u.grab_point = d_sum; // furniture moved relative to us
11614  } else { // we pushed furniture out of reach
11615  add_msg( _( "You let go of the %s." ), furntype.name() );
11617  }
11618  return true; // We moved furniture but stayed still.
11619  }
11620 
11621  if( pushing_furniture && m.impassable( fpos ) ) {
11622  // Not sure how that chair got into a wall, but don't let player follow.
11623  add_msg( _( "You let go of the %1$s as it slides past %2$s." ),
11624  furntype.name(), m.tername( fdest ) );
11626  return true;
11627  }
11628 
11629  return false;
11630 }
int get_perceived_pain() const override
Returns perceived pain (reduced with painkillers)
int get_arm_str() const
Definition: character.cpp:4200
void grab(object_type grab_type, const tripoint &grab_point=tripoint_zero)
Definition: avatar.cpp:699
std::vector< std::string > get_dangerous_tile(const tripoint &dest_loc) const
Definition: game.cpp:10433
bool can_move_furniture(tripoint fdest, const tripoint &dp)
Definition: game.cpp:11356
void insert(const item &newitem) override
Definition: map.cpp:224
void remove_field(const tripoint &p, const field_type_id &field_to_remove)
Remove field entry at xy, ignored if the field entry is not present.
Definition: map.cpp:6630
time_duration set_field_age(const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
Set age of field entry at point.
Definition: map.cpp:6434
time_duration get_field_age(const tripoint &p, const field_type_id &type) const
Get the age of a field entry (field_entry::age), if there is no field of that type,...
Definition: map.cpp:6465
void drop_furniture(const tripoint &p)
Definition: map.cpp:2762
int get_field_intensity(const tripoint &p, const field_type_id &type) const
Get the intensity of a field entry (field_entry::intensity), if there is no field of that type,...
Definition: map.cpp:6476
int set_field_intensity(const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.
Definition: map.cpp:6447
std::string tername(const tripoint &p) const
Definition: map.cpp:2340
void i_clear(const tripoint &p)
Definition: map.cpp:5030
static const string_id< furn_t > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
const field_type_str_id fd_fire("fd_fire")
static const trait_id trait_MASOCHIST_MED("MASOCHIST_MED")
static const trait_id trait_CENOBITE("CENOBITE")
static const trait_id trait_MASOCHIST("MASOCHIST")
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:318
int move_str_req
Definition: mapdata.h:658
bool has_flag(const std::string &flag) const
Definition: mapdata.h:534

References _, abs(), add_msg(), item_stack::begin(), can_move_furniture(), map::drop_furniture(), item_stack::end(), enumerate_as_string(), fd_fire, map::furn(), map::furn_set(), Character::get_arm_str(), get_dangerous_tile(), map::get_field_age(), map::get_field_intensity(), Character::get_perceived_pain(), avatar::grab(), Character::grab_point, map_data_common_t::has_flag(), map::has_flag(), map::has_floor_or_water(), map::has_furn(), Character::has_trait(), map::i_at(), map::i_clear(), map::impassable(), map_stack::insert(), m, m_bad, m_info, max(), Character::mod_pain(), furn_t::move_str_req, sounds::movement, map_data_common_t::name(), NONE, string_id< furn_t >::NULL_ID(), int_id< T >::obj(), one_in(), Creature::pos(), map::remove_field(), map::set_field_age(), map::set_field_intensity(), item_stack::size(), sounds::sound(), temp, map::tername(), TFLAG_CONTAINER, TFLAG_DESTROY_ITEM, TFLAG_FIRE_CONTAINER, TFLAG_FLAT, TFLAG_NOITEM, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_SEALED, TFLAG_SWIMMABLE, trait_CENOBITE, trait_MASOCHIST, trait_MASOCHIST_MED, tripoint, u, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

◆ grabbed_furn_move_time()

int game::grabbed_furn_move_time ( const tripoint dp)

Definition at line 11375 of file game.cpp.

11376 {
11377  // Furniture: pull, push, or standing still and nudging object around.
11378  // Can push furniture out of reach.
11379  tripoint fpos = u.pos() + u.grab_point;
11380  // supposed position of grabbed furniture
11381  if( !m.has_furn( fpos ) ) {
11382  return 0;
11383  }
11384 
11385  tripoint fdest = fpos + tripoint( dp.xy(), 0 ); // intended destination of furniture.
11386 
11387  const bool canmove = can_move_furniture( fdest, dp );
11388  const furn_t &furntype = m.furn( fpos ).obj();
11389  const int dst_items = m.i_at( fdest ).size();
11390 
11391  const bool only_liquid_items = std::all_of( m.i_at( fdest ).begin(), m.i_at( fdest ).end(),
11392  [&]( item & liquid_item ) {
11393  return liquid_item.made_of_from_type( phase_id::LIQUID );
11394  } );
11395 
11396  const bool dst_item_ok = !m.has_flag( ter_furn_flag::TFLAG_NOITEM, fdest ) &&
11399  only_liquid_items;
11400  const bool src_item_ok = m.furn( fpos ).obj().has_flag( ter_furn_flag::TFLAG_CONTAINER ) ||
11403 
11404  int str_req = furntype.move_str_req;
11405  // Factor in weight of items contained in the furniture.
11406  units::mass furniture_contents_weight = 0_gram;
11407  for( item &contained_item : m.i_at( fpos ) ) {
11408  furniture_contents_weight += contained_item.weight();
11409  }
11410  str_req += furniture_contents_weight / 4_kilogram;
11411  //ARM_STR affects dragging furniture
11412  int str = u.get_arm_str();
11413 
11414  const float weary_mult = 1.0f / u.exertion_adjusted_move_multiplier();
11415  if( !canmove ) { // NOLINT(bugprone-branch-clone)
11416  return 50 * weary_mult;
11417  } else if( str_req > str &&
11418  one_in( std::max( 20 - ( str_req - str ), 2 ) ) ) {
11419  return 100 * weary_mult;
11420  } else if( !src_item_ok && !dst_item_ok && dst_items > 0 ) {
11421  return 50 * weary_mult;
11422  }
11423  int moves_total = 0;
11424  moves_total = str_req * 10;
11425  // Additional penalty if we can't comfortably move it.
11426  if( str_req > str ) {
11427  int move_penalty = std::pow( str_req, 2.0 ) + 100.0;
11428  if( move_penalty <= 1000 ) {
11429  if( str >= str_req - 3 ) {
11430  moves_total += std::max( 3000, move_penalty * 10 ) * weary_mult;
11431  } else {
11432  moves_total += 100 * weary_mult;
11433  return moves_total;
11434  }
11435  }
11436  moves_total += move_penalty;
11437  }
11438  return moves_total;
11439 }

References item_stack::begin(), can_move_furniture(), item_stack::end(), Character::exertion_adjusted_move_multiplier(), map::furn(), Character::get_arm_str(), Character::grab_point, map_data_common_t::has_flag(), map::has_flag(), map::has_furn(), map::i_at(), m, max(), furn_t::move_str_req, int_id< T >::obj(), one_in(), Creature::pos(), item_stack::size(), TFLAG_CONTAINER, TFLAG_DESTROY_ITEM, TFLAG_FIRE_CONTAINER, TFLAG_NOITEM, TFLAG_SEALED, TFLAG_SWIMMABLE, tripoint, u, and tripoint::xy().

◆ grabbed_move()

bool game::grabbed_move ( const tripoint dp,
bool  via_ramp 
)
private

Check for dangerous stuff at dest_loc, return false if the player decides not to step there.

Definition at line 11632 of file game.cpp.

11633 {
11634  if( u.get_grab_type() == object_type::NONE ) {
11635  return false;
11636  }
11637 
11638  // vehicle: pulling, pushing, or moving around the grabbed object.
11639  if( u.get_grab_type() == object_type::VEHICLE ) {
11640  return grabbed_veh_move( dp );
11641  }
11642 
11644  u.assign_activity( move_furniture_activity_actor( dp, via_ramp ) );
11645  return true;
11646  }
11647 
11648  add_msg( m_info, _( "Nothing at grabbed point %d,%d,%d or bad grabbed object type." ),
11651  return false;
11652 }
object_type get_grab_type() const
Definition: avatar.cpp:733
bool grabbed_veh_move(const tripoint &dp)
Definition: grab.cpp:19

References _, add_msg(), Character::assign_activity(), FURNITURE, avatar::get_grab_type(), avatar::grab(), Character::grab_point, grabbed_veh_move(), m_info, NONE, u, VEHICLE, tripoint::x, tripoint::y, and tripoint::z.

Referenced by walk_move().

◆ grabbed_veh_move()

bool game::grabbed_veh_move ( const tripoint dp)
private

\ARM_STR determines ability to drag vehicles

Strength increases speed of dragging vehicles Strength decreases stamina cost of dragging vehicles

Definition at line 19 of file grab.cpp.

20 {
21  const optional_vpart_position grabbed_vehicle_vp = m.veh_at( u.pos() + u.grab_point );
22  if( !grabbed_vehicle_vp ) {
23  add_msg( m_info, _( "No vehicle at grabbed point." ) );
25  return false;
26  }
27  vehicle *grabbed_vehicle = &grabbed_vehicle_vp->vehicle();
28  if( !grabbed_vehicle ||
29  !grabbed_vehicle->handle_potential_theft( get_avatar() ) ) {
30  return false;
31  }
32  const int grabbed_part = grabbed_vehicle_vp->part_index();
33  if( monster *mon = grabbed_vehicle->get_harnessed_animal() ) {
34  add_msg( m_info, _( "You cannot move this vehicle whilst your %s is harnessed!" ),
35  mon->get_name() );
37  return false;
38  }
39  const vehicle *veh_under_player = veh_pointer_or_null( m.veh_at( u.pos() ) );
40  if( grabbed_vehicle == veh_under_player ) {
41  u.grab_point = -dp;
42  return false;
43  }
44 
45  tripoint dp_veh = -u.grab_point;
46  const tripoint prev_grab = u.grab_point;
47  tripoint next_grab = u.grab_point;
48 
49  bool zigzag = false;
50 
51  if( dp == prev_grab ) {
52  // We are pushing in the direction of vehicle
53  dp_veh = dp;
54  } else if( std::abs( dp.x + dp_veh.x ) != 2 && std::abs( dp.y + dp_veh.y ) != 2 ) {
55  // Not actually moving the vehicle, don't do the checks
56  u.grab_point = -( dp + dp_veh );
57  return false;
58  } else if( ( dp.x == prev_grab.x || dp.y == prev_grab.y ) &&
59  next_grab.x != 0 && next_grab.y != 0 ) {
60  // Zig-zag (or semi-zig-zag) pull: player is diagonal to vehicle
61  // and moves away from it, but not directly away
62  dp_veh.x = dp.x == -dp_veh.x ? 0 : dp_veh.x;
63  dp_veh.y = dp.y == -dp_veh.y ? 0 : dp_veh.y;
64 
65  next_grab = -dp_veh;
66  zigzag = true;
67  } else {
68  // We are pulling the vehicle
69  next_grab = -dp;
70  }
71 
72  // Make sure the mass and pivot point are correct
73  grabbed_vehicle->invalidate_mass();
74 
75  //vehicle movement: strength check. very strong humans can move about 2,000 kg in a wheelbarrow.
76  int mc = 0;
77  // worst case scenario strength required to move vehicle.
78  const int max_str_req = grabbed_vehicle->total_mass() / 10_kilogram;
79  // actual strength required to move vehicle.
80  int str_req = 0;
81  // ARM_STR governs dragging heavy things
82  int str = u.get_arm_str();
83 
84  //if vehicle is rollable we modify str_req based on a function of movecost per wheel.
85 
86  const auto &wheel_indices = grabbed_vehicle->wheelcache;
87  if( grabbed_vehicle->valid_wheel_config() ) {
88  str_req = max_str_req / 10;
89  //determine movecost for terrain touching wheels
90  const tripoint_bub_ms vehpos = grabbed_vehicle->pos_bub();
91  for( int p : wheel_indices ) {
92  const tripoint_bub_ms wheel_pos = vehpos + grabbed_vehicle->part( p ).precalc[0];
93  const int mapcost = m.move_cost( wheel_pos, grabbed_vehicle );
94  mc += str_req / wheel_indices.size() * mapcost;
95  }
96  //set strength check threshold
97  //if vehicle has many or only one wheel (shopping cart), it is as if it had four.
98  if( wheel_indices.size() > 4 || wheel_indices.size() == 1 ) {
99  str_req = mc / 4 + 1;
100  } else {
101  str_req = mc / wheel_indices.size() + 1;
102  }
103  //finally, adjust by the off-road coefficient (always 1.0 on a road, as low as 0.1 off road.)
104  str_req /= grabbed_vehicle->k_traction( get_map().vehicle_wheel_traction( *grabbed_vehicle ) );
105  // If it would be easier not to use the wheels, don't use the wheels.
106  str_req = std::min( str_req, max_str_req );
107  } else {
108  str_req = max_str_req;
109  //if vehicle has no wheels str_req make a noise. since it has no wheels assume it has the worst off roading possible (0.1)
110  if( str_req <= str ) {
111  sounds::sound( grabbed_vehicle->global_pos3(), str_req * 2, sounds::sound_t::movement,
112  _( "a scraping noise." ), true, "misc", "scraping" );
113  }
114  }
115 
116  //final strength check and outcomes
117  ///\ARM_STR determines ability to drag vehicles
118  if( str_req <= str ) {
119  //calculate exertion factor and movement penalty
120  ///\EFFECT_STR increases speed of dragging vehicles
121  u.mod_moves( -to_moves<int>( 4_seconds ) * str_req / std::max( 1, str ) );
122  ///\EFFECT_STR decreases stamina cost of dragging vehicles
123  u.burn_energy_all( -200 * str_req / std::max( 1, str ) );
124  const int ex = dice( 1, 6 ) - 1 + str_req;
125  if( ex > str + 1 ) {
126  // Pain and movement penalty if exertion exceeds character strength
127  add_msg( m_bad, _( "You strain yourself to move the %s!" ), grabbed_vehicle->name );
128  u.mod_moves( -to_moves<int>( 2_seconds ) );
129  u.mod_pain( 1 );
130  } else if( ex >= str ) {
131  // Movement is slow if exertion nearly equals character strength
132  add_msg( _( "It takes some time to move the %s." ), grabbed_vehicle->name );
133  u.mod_moves( -to_moves<int>( 2_seconds ) );
134  }
135  } else {
136  u.mod_moves( -to_moves<int>( 1_seconds ) );
137  add_msg( m_bad, _( "You lack the strength to move the %s." ), grabbed_vehicle->name );
138  return true;
139  }
140 
141  std::string blocker_name = _( "errors in movement code" );
142  const auto get_move_dir = [&]( const tripoint & dir, const tripoint & from ) {
143  tileray mdir;
144 
145  mdir.init( dir.xy() );
146  units::angle turn = normalize( mdir.dir() - grabbed_vehicle->face.dir() );
147  if( grabbed_vehicle->is_on_ramp && turn == 180_degrees ) {
148  add_msg( m_bad, _( "The %s can't be turned around while on a ramp." ), grabbed_vehicle->name );
149  return tripoint_zero;
150  }
151  grabbed_vehicle->turn( turn );
152  grabbed_vehicle->face = tileray( grabbed_vehicle->turn_dir );
153  grabbed_vehicle->precalc_mounts( 1, mdir.dir(), grabbed_vehicle->pivot_point() );
154  grabbed_vehicle->pos -= grabbed_vehicle->pivot_displacement();
155 
156  // Grabbed part has to stay at distance 1 to the player
157  // and in roughly the same direction.
158  const tripoint new_part_pos = grabbed_vehicle->global_pos3() +
159  grabbed_vehicle->part( grabbed_part ).precalc[ 1 ];
160  const tripoint expected_pos = u.pos() + dp + from;
161  const tripoint actual_dir = tripoint( ( expected_pos - new_part_pos ).xy(), 0 );
162 
163  // Set player location to illegal value so it can't collide with vehicle.
164  const tripoint player_prev = u.pos();
166  std::vector<veh_collision> colls;
167  const bool failed = grabbed_vehicle->collision( colls, actual_dir, true );
168  u.setpos( player_prev );
169  if( !colls.empty() ) {
170  blocker_name = colls.front().target_name;
171  }
172  return failed ? tripoint_zero : actual_dir;
173  };
174 
175  // First try the move as intended
176  // But if that fails and the move is a zig-zag, try to recover:
177  // Try to place the vehicle in the position player just left rather than "flattening" the zig-zag
178  tripoint final_dp_veh = get_move_dir( dp_veh, next_grab );
179  if( final_dp_veh == tripoint_zero && zigzag ) {
180  final_dp_veh = get_move_dir( -prev_grab, -dp );
181  next_grab = -dp;
182  }
183 
184  if( final_dp_veh == tripoint_zero ) {
185  add_msg( _( "The %s collides with %s." ), grabbed_vehicle->name, blocker_name );
186  u.grab_point = prev_grab;
187  return true;
188  }
189 
190  u.grab_point = next_grab;
191 
192  m.displace_vehicle( *grabbed_vehicle, final_dp_veh );
194 
195  if( grabbed_vehicle ) {
196  m.level_vehicle( *grabbed_vehicle );
197  grabbed_vehicle->check_falling_or_floating();
198  if( grabbed_vehicle->is_falling ) {
199  add_msg( _( "You let go of the %1$s as it starts to fall." ), grabbed_vehicle->disp_name() );
201  m.drop_vehicle( final_dp_veh );
202  return true;
203  }
204  } else {
205  debugmsg( "Grabbed vehicle disappeared" );
206  return false;
207  }
208 
209  for( int p : wheel_indices ) {
210  if( one_in( 2 ) ) {
211  vehicle_part &vp_wheel = grabbed_vehicle->part( p );
212  tripoint wheel_p = grabbed_vehicle->global_part_pos3( vp_wheel );
213  grabbed_vehicle->handle_trap( wheel_p, vp_wheel );
214  }
215  }
216 
217  return false;
218 
219 }
void burn_energy_all(int mod)
Definition: character.cpp:6932
void rebuild_vehicle_level_caches()
Definition: map.cpp:443
float vehicle_wheel_traction(const vehicle &veh, bool ignore_movement_modifiers=false) const
void drop_vehicle(const tripoint &p)
Definition: map.cpp:3022
int move_cost(const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
Calculate the cost to move past the tile at p.
Definition: map.cpp:2434
bool displace_vehicle(vehicle &veh, const tripoint &dp, bool adjust_pos=true, const std::set< int > &parts_to_move={})
Definition: map.cpp:1435
void level_vehicle(vehicle &veh)
Definition: map.cpp:1631
units::angle dir() const
Definition: tileray.cpp:73
void init(const point &ad)
Definition: tileray.cpp:26
point pos
Position of the vehicle inside the submap that contains the vehicle.
Definition: vehicle.h:2274
void turn(units::angle deg)
const point & pivot_point() const
Definition: vehicle.cpp:6547
bool is_on_ramp
Definition: vehicle.h:2345
tripoint global_pos3() const
Definition: vehicle.cpp:3431
bool valid_wheel_config() const
Definition: vehicle.cpp:4764
units::mass total_mass() const
Definition: vehicle.cpp:3472
std::vector< int > wheelcache
Definition: vehicle.h:2183
void check_falling_or_floating()
tileray face
Definition: vehicle.h:2312
void invalidate_mass()
Mark mass caches and pivot cache as dirty.
Definition: vehicle.cpp:7986
float k_traction(float wheel_traction_area) const
Traction coefficient of the vehicle.
Definition: vehicle.cpp:4560
bool collision(std::vector< veh_collision > &colls, const tripoint &dp, bool just_detect, bool bash_floor=false)
void handle_trap(const tripoint &p, vehicle_part &vp_wheel)
void precalc_mounts(int idir, const units::angle &dir, const point &pivot)
Definition: vehicle.cpp:3338
vehicle_part & part(int part_num)
Definition: vehicle.cpp:8098
std::string disp_name() const
tripoint_bub_ms pos_bub() const
Definition: vehicle.cpp:3436
tripoint global_part_pos3(const int &index) const
Get the coordinates of the studied part of the vehicle.
Definition: vehicle.cpp:3442
bool is_falling
Definition: vehicle.h:2369
units::angle turn_dir
Definition: vehicle.h:2291
point pivot_displacement() const
Definition: vehicle.cpp:3501
constexpr tripoint tripoint_zero
Definition: point.h:250
int dice(int number, int sides)
Definition: rng.cpp:123
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:254
std::array< tripoint, 2 > precalc
mount translated to face.dir [0] and turn_dir [1]
Definition: vehicle.h:451
units::angle normalize(units::angle a, units::angle mod)
Given an angle, add or subtract multiples of 360_degrees until it's in the range [0,...
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, abs(), add_msg(), Character::burn_energy_all(), vehicle::check_falling_or_floating(), vehicle::collision(), debugmsg, dice(), tileray::dir(), vehicle::disp_name(), map::displace_vehicle(), map::drop_vehicle(), vehicle::face, failed, Character::get_arm_str(), get_avatar, vehicle::get_harnessed_animal(), get_map, vehicle::global_part_pos3(), vehicle::global_pos3(), avatar::grab(), Character::grab_point, vehicle::handle_potential_theft(), vehicle::handle_trap(), tileray::init(), vehicle::invalidate_mass(), vehicle::is_falling, vehicle::is_on_ramp, vehicle::k_traction(), map::level_vehicle(), m, m_bad, m_info, max(), min(), Creature::mod_moves(), Character::mod_pain(), map::move_cost(), sounds::movement, vehicle::name, NONE, normalize(), one_in(), vehicle::part(), vehicle::pivot_displacement(), vehicle::pivot_point(), Creature::pos(), vehicle::pos, vehicle::pos_bub(), vehicle_part::precalc, vehicle::precalc_mounts(), map::rebuild_vehicle_level_caches(), Creature::setpos(), sounds::sound(), vehicle::total_mass(), tripoint, tripoint_zero, calendar::turn, vehicle::turn(), vehicle::turn_dir, u, vehicle::valid_wheel_config(), map::veh_at(), veh_pointer_or_null(), map::vehicle_wheel_traction(), vehicle::wheelcache, tripoint::x, tripoint::xy(), and tripoint::y.

Referenced by grabbed_move().

◆ handle_action()

bool game::handle_action ( )
private

Definition at line 2979 of file handle_action.cpp.

2980 {
2981  std::string action;
2982  input_context ctxt;
2984  user_turn current_turn;
2985  avatar &player_character = get_avatar();
2986  // Check if we have an auto-move destination
2987  if( player_character.has_destination() ) {
2988  act = player_character.get_next_auto_move_direction();
2989  if( act == ACTION_NULL ) {
2990  add_msg( m_info, _( "Auto-move canceled" ) );
2991  player_character.clear_destination();
2992  return false;
2993  }
2995  } else if( player_character.has_destination_activity() ) {
2996  // starts destination activity after the player successfully reached his destination
2997  player_character.start_destination_activity();
2998  return false;
2999  } else {
3000  // No auto-move, ask player for input
3001  ctxt = get_player_input( action );
3002  }
3003 
3004  // Remove asynchronous animations if any action taken before the input timeout
3005  // Otherwise repeated input can cause animations to accumulate as the timeout is never reached
3006  g->void_async_anim_curses();
3007 #if defined(TILES)
3008  tilecontext->void_async_anim();
3009 #else
3010  // Curses does not redraw itself so do it here
3011  g->invalidate_main_ui_adaptor();
3012 #endif
3013 
3014  bool veh_ctrl = has_vehicle_control( player_character );
3015 
3016  // If performing an action with right mouse button, co-ordinates
3017  // of location clicked.
3018  std::optional<tripoint> mouse_target;
3019 
3020  if( uquit == QUIT_WATCH && action == "QUIT" ) {
3021  uquit = QUIT_DIED;
3022  return false;
3023  }
3024 
3025  if( act == ACTION_NULL ) {
3026  act = look_up_action( action );
3027 
3028  if( act == ACTION_KEYBINDINGS ) {
3029  // already handled by input context
3030  return false;
3031  }
3032 
3033  if( act == ACTION_MAIN_MENU ) {
3034  if( uquit == QUIT_WATCH ) {
3035  return false;
3036  }
3037  // No auto-move actions have or can be set at this point.
3038  player_character.clear_destination();
3039  destination_preview.clear();
3040  act = handle_main_menu();
3041  if( act == ACTION_NULL ) {
3042  return false;
3043  }
3044  }
3045 
3046  if( act == ACTION_ACTIONMENU ) {
3047  if( uquit == QUIT_WATCH ) {
3048  return false;
3049  }
3050  // No auto-move actions have or can be set at this point.
3051  player_character.clear_destination();
3052  destination_preview.clear();
3053  act = handle_action_menu();
3054  if( act == ACTION_NULL ) {
3055  return false;
3056  }
3057 #if defined(__ANDROID__)
3058  if( get_option<bool>( "ANDROID_ACTIONMENU_AUTOADD" ) && ctxt.get_category() == "DEFAULTMODE" ) {
3059  add_best_key_for_action_to_quick_shortcuts( act, ctxt.get_category(), false );
3060  }
3061 #endif
3062  }
3063 
3064  if( act == ACTION_KEYBINDINGS ) {
3065  player_character.clear_destination();
3066  destination_preview.clear();
3067  act = ctxt.display_menu( true );
3068  if( act == ACTION_NULL ) {
3069  return false;
3070  }
3071  }
3072 
3074  user_action_counter += 1;
3075  }
3076 
3077  if( act == ACTION_CLICK_AND_DRAG ) {
3078  // Need to return false to avoid disrupting actions like character mouse movement that require two clicks
3079  return false;
3080  }
3081 
3082  if( act == ACTION_SELECT || act == ACTION_SEC_SELECT ) {
3083  // Mouse button click
3084  if( veh_ctrl ) {
3085  // No mouse use in vehicle
3086  return false;
3087  }
3088 
3089  if( player_character.is_dead_state() ) {
3090  // do not allow mouse actions while dead
3091  return false;
3092  }
3093 
3094  const std::optional<tripoint> mouse_pos = ctxt.get_coordinates( w_terrain, ter_view_p.xy(), true );
3095  if( !mouse_pos ) {
3096  return false;
3097  }
3098  if( !player_character.sees( *mouse_pos ) ) {
3099  // Not clicked in visible terrain
3100  return false;
3101  }
3102  mouse_target = mouse_pos;
3103 
3104  if( act == ACTION_SELECT ) {
3105  // Note: The following has the potential side effect of
3106  // setting auto-move destination state in addition to setting
3107  // act.
3108  // TODO: fix point types
3109  if( !try_get_left_click_action( act, tripoint_bub_ms( *mouse_target ) ) ) {
3110  return false;
3111  }
3112  } else if( act == ACTION_SEC_SELECT ) {
3113  // TODO: fix point types
3114  if( !try_get_right_click_action( act, tripoint_bub_ms( *mouse_target ) ) ) {
3115  return false;
3116  }
3117  }
3118  } else if( act != ACTION_TIMEOUT ) {
3119  // act has not been set for an auto-move, so clearing possible
3120  // auto-move destinations. Since initializing an auto-move with
3121  // the mouse may span across multiple actions, we do not clear the
3122  // auto-move destination if the action is only a timeout, as this
3123  // would require the user to double click quicker than the
3124  // timeout delay.
3125  player_character.clear_destination();
3126  destination_preview.clear();
3127  }
3128  }
3129 
3130  if( act == ACTION_NULL ) {
3131  const input_event &&evt = ctxt.get_raw_input();
3132  if( !evt.sequence.empty() ) {
3133  const int ch = evt.get_first_input();
3134  if( !get_option<bool>( "NO_UNKNOWN_COMMAND_MSG" ) ) {
3135  std::string msg = string_format( _( "Unknown command: \"%s\" (%ld)" ), evt.long_description(), ch );
3136  if( const std::optional<std::string> hint =
3138  msg = string_format( "%s\n%s", msg,
3139  string_format( _( "%s at any time to see and edit keybindings relevant to "
3140  "the current context." ),
3141  *hint ) );
3142  }
3143  add_msg( m_info, msg );
3144  }
3145  }
3146  return false;
3147  }
3148 
3149  // This has no action unless we're in a special game mode.
3150  gamemode->pre_action( act );
3151 
3152  int before_action_moves = player_character.get_moves();
3153 
3154  // These actions are allowed while deathcam is active. Registered in game::get_player_input
3155  if( uquit == QUIT_WATCH || !player_character.is_dead_state() ) {
3156  do_deathcam_action( act, player_character );
3157  }
3158 
3159  // actions allowed only while alive
3160  if( !player_character.is_dead_state() ) {
3161  if( !do_regular_action( act, player_character, mouse_target ) ) {
3162  return false;
3163  }
3164  }
3165  if( act != ACTION_TIMEOUT ) {
3166  player_character.mod_moves( -current_turn.moves_elapsed() );
3167  }
3168  gamemode->post_action( act );
3169 
3170  player_character.movecounter = ( !player_character.is_dead_state() ? ( before_action_moves -
3171  player_character.get_moves() ) : 0 );
3172  dbg( D_INFO ) << string_format( "%s: [%d] %d - %d = %d", action_ident( act ),
3173  to_turn<int>( calendar::turn ), before_action_moves, player_character.movecounter,
3174  player_character.get_moves() );
3175  return !player_character.is_dead_state();
3176 }
std::optional< std::string > press_x_if_bound(action_id act)
Definition: action.cpp:545
bool can_action_change_worldstate(const action_id act)
Lookup whether an action can affect the state of the game world.
Definition: action.cpp:422
action_id look_up_action(const std::string &ident)
Lookup an action ID by its unique string identifier.
Definition: action.cpp:494
action_id handle_main_menu()
Show in-game main menu.
Definition: action.cpp:1053
action_id handle_action_menu()
Show the action menu.
Definition: action.cpp:756
@ ACTION_SEC_SELECT
Click on a point with secondary mouse button (usually right button)
Definition: action.h:30
@ ACTION_SELECT
Click on a point with primary mouse button (usually left button)
Definition: action.h:28
@ ACTION_CLICK_AND_DRAG
action on left mouse button-down, for clicking and dragging
Definition: action.h:32
bool has_destination_activity() const
void start_destination_activity()
bool is_dead_state() const override
Returns true if the player should be dead.
Definition: character.cpp:1885
int get_moves() const
Definition: creature.cpp:2004
int movecounter
Definition: avatar.h:367
bool try_get_right_click_action(action_id &act, const tripoint_bub_ms &mouse_target)
Definition: game.cpp:2689
input_context get_player_input(std::string &action)
bool do_regular_action(action_id &act, avatar &player_character, const std::optional< tripoint > &mouse_target)
bool try_get_left_click_action(action_id &act, const tripoint_bub_ms &mouse_target)
Definition: game.cpp:2655
input_event get_raw_input()
Temporary method to retrieve the raw input received, so that input_contexts can be used in screens wh...
std::optional< tripoint > get_coordinates(const catacurses::window &capture_win_, const point &offset=point_zero, bool center_cursor=false) const
Get the coordinates associated with the last mouse click (if any).
action_id display_menu(bool permit_execute_action=false)
Display the possible actions in the current context and their keybindings.
int moves_elapsed()
@ D_INFO
Definition: debug.h:140
void handle_key_blocking_activity()
Definition: do_turn.cpp:225
@ QUIT_DIED
Definition: game.h:57
#define dbg(x)
static void do_deathcam_action(const action_id &act, avatar &player_character)
An instance of an input, like a keypress etc.
Definition: input_enums.h:63
std::vector< int > sequence
Definition: input_enums.h:69
int get_first_input() const
Definition: input.cpp:98
std::string long_description() const
Definition: input.cpp:118

References _, act, action, ACTION_ACTIONMENU, ACTION_CLICK_AND_DRAG, action_ident(), ACTION_KEYBINDINGS, ACTION_MAIN_MENU, ACTION_NULL, ACTION_SEC_SELECT, ACTION_SELECT, ACTION_TIMEOUT, add_msg(), can_action_change_worldstate(), Character::clear_destination(), D_INFO, dbg, destination_preview, input_context::display_menu(), do_deathcam_action(), do_regular_action(), g, gamemode, get_avatar, input_context::get_coordinates(), input_event::get_first_input(), Creature::get_moves(), Character::get_next_auto_move_direction(), get_player_input(), input_context::get_raw_input(), handle_action_menu(), handle_key_blocking_activity(), handle_main_menu(), Character::has_destination(), Character::has_destination_activity(), has_vehicle_control(), Character::is_dead_state(), input_event::long_description(), look_up_action(), m_info, Creature::mod_moves(), avatar::movecounter, user_turn::moves_elapsed(), press_x_if_bound(), QUIT_DIED, QUIT_WATCH, Character::sees(), input_event::sequence, Character::start_destination_activity(), string_format(), ter_view_p, try_get_left_click_action(), try_get_right_click_action(), calendar::turn, uquit, user_action_counter, w_terrain, and tripoint::xy().

◆ handle_mouseview()

bool game::handle_mouseview ( input_context ctxt,
std::string &  action 
)
private

Definition at line 2355 of file game.cpp.

2356 {
2357  std::optional<tripoint> liveview_pos;
2358 
2359  do {
2360  action = ctxt.handle_input();
2361  if( action == "MOUSE_MOVE" ) {
2362  const std::optional<tripoint> mouse_pos = ctxt.get_coordinates( w_terrain, ter_view_p.xy(), true );
2363  if( mouse_pos && ( !liveview_pos || *mouse_pos != *liveview_pos ) ) {
2364  liveview_pos = mouse_pos;
2365  liveview.show( *liveview_pos );
2366  } else if( !mouse_pos ) {
2367  liveview_pos.reset();
2368  liveview.hide();
2369  }
2371  }
2372  } while( action == "MOUSE_MOVE" ); // Freeze animation when moving the mouse
2373 
2374  if( action != "TIMEOUT" ) {
2375  // Keyboard event, break out of animation loop
2376  liveview.hide();
2377  return false;
2378  }
2379 
2380  // Mouse movement or un-handled key
2381  return true;
2382 }
const std::string & handle_input()
Handles input and returns the next action in the queue.
void hide()
Definition: live_view.cpp:35
void show(const tripoint &p)
Definition: live_view.cpp:40

References action, input_context::get_coordinates(), input_context::handle_input(), live_view::hide(), liveview, ui_manager::redraw(), live_view::show(), ter_view_p, w_terrain, and tripoint::xy().

Referenced by get_player_input().

◆ has_blink_curses()

bool game::has_blink_curses ( )

Definition at line 3964 of file game.cpp.

3965 {
3966  return !blink_layer_curses.empty();
3967 }

References blink_layer_curses.

◆ has_gametype()

bool game::has_gametype ( ) const

Definition at line 833 of file game.cpp.

834 {
835  return gamemode && gamemode->id() != special_game_type::NONE;
836 }

References gamemode, and NONE.

◆ init_autosave()

void game::init_autosave ( )
private

Definition at line 13038 of file game.cpp.

13039 {
13041  last_save_timestamp = std::time( nullptr );
13042 }

References last_save_timestamp, and moves_since_last_save.

Referenced by load(), and start_game().

◆ init_draw_async_anim_curses()

void game::init_draw_async_anim_curses ( const tripoint p,
const std::string &  ncstr,
const nc_color nccol 
)

Definition at line 3912 of file game.cpp.

3914 {
3915  std::pair <std::string, nc_color> anim( ncstr, nccol );
3916  async_anim_layer_curses[p] = anim;
3917 }

References async_anim_layer_curses.

◆ init_draw_blink_curses()

void game::init_draw_blink_curses ( const tripoint p,
const std::string &  ncstr,
const nc_color nccol 
)

Definition at line 3938 of file game.cpp.

3940 {
3941  std::pair <std::string, nc_color> anim( ncstr, nccol );
3942  blink_layer_curses[p] = anim;
3943 }

References blink_layer_curses.

Referenced by draw_critter().

◆ insert_item() [1/2]

void game::insert_item ( )

Definition at line 9315 of file game.cpp.

9316 {
9317  item_location item_loc = inv_map_splice( [&]( const item_location & it ) {
9318  return it->is_container() && !it->is_corpse() && rate_action_insert( u, it ) == hint_rating::good;
9319  }, _( "Insert item" ), 1, _( "You have no container to insert items." ) );
9320 
9321  if( !item_loc ) {
9322  add_msg( _( "Never mind." ) );
9323  return;
9324  }
9325 
9326  game_menus::inv::insert_items( u, item_loc );
9327 }
item_location inv_map_splice(const item_filter &filter, const std::string &title, int radius=0, const std::string &none_message="")
Custom-filtered menu for inventory and nearby items and those that within specified radius.
bool is_container() const
Whether this is container.
Definition: item.cpp:9667
bool is_corpse() const
Whether this is a corpse item.
Definition: item.cpp:9526
static hint_rating rate_action_insert(const avatar &you, const item_location &loc)
Definition: game.cpp:2013
@ good
Item permits this action.
void insert_items(avatar &you, item_location &holster)

References _, add_msg(), good, game_menus::inv::insert_items(), inv_map_splice(), item::is_container(), item::is_corpse(), rate_action_insert(), and u.

Referenced by do_regular_action().

◆ insert_item() [2/2]

void game::insert_item ( drop_locations targets)

Definition at line 9293 of file game.cpp.

9294 {
9295  if( targets.empty() || !targets.front().first ) {
9296  return;
9297  }
9298  std::string title = string_format( _( "%s: %s and %d items" ), _( "Insert item" ),
9299  targets.front().first->tname(), targets.size() - 1 );
9300  item_location item_loc = inv_map_splice( [ &, targets]( const item_location & it ) {
9301  if( targets.front().first.parent_item() == it ) {
9302  return false;
9303  }
9304  return it->is_container() && !it->is_corpse() && rate_action_insert( u, it ) == hint_rating::good;
9305  }, title, 1, _( "You have no container to insert items." ) );
9306 
9307  if( !item_loc ) {
9308  add_msg( _( "Never mind." ) );
9309  return;
9310  }
9311 
9312  u.assign_activity( insert_item_activity_actor( item_loc, targets, true ) );
9313 }

References _, add_msg(), Character::assign_activity(), good, inv_map_splice(), item::is_container(), item::is_corpse(), rate_action_insert(), string_format(), music::title, and u.

◆ inv_map_splice() [1/2]

item_location game::inv_map_splice ( const item_filter filter,
const std::string &  title,
int  radius = 0,
const std::string &  none_message = "" 
)

Custom-filtered menu for inventory and nearby items and those that within specified radius.

Definition at line 455 of file game_inventory.cpp.

457 {
459  title, radius, none_message );
460 }
static item_location_filter convert_filter(const item_filter &filter)
static item_location inv_internal(Character &u, const inventory_selector_preset &preset, const std::string &title, int radius, const std::string &none_message, const std::string &hint=std::string(), item_location container=item_location())

References convert_filter(), filter, inv_internal(), music::title, and u.

Referenced by insert_item(), and reload_item().

◆ inv_map_splice() [2/2]

item_location game::inv_map_splice ( const item_location_filter filter,
const std::string &  title,
int  radius = 0,
const std::string &  none_message = "" 
)

Definition at line 462 of file game_inventory.cpp.

464 {
466  title, radius, none_message );
467 }

References filter, inv_internal(), music::title, and u.

◆ invalidate_main_ui_adaptor()

void game::invalidate_main_ui_adaptor ( ) const

Definition at line 3798 of file game.cpp.

3799 {
3801  if( ui ) {
3802  ui->invalidate_ui();
3803  }
3804 }

References main_ui_adaptor.

Referenced by add_draw_callback(), fling_creature(), get_player_input(), list_items(), list_monsters(), look_around(), and zones_manager().

◆ inventory_item_menu()

int game::inventory_item_menu ( item_location  locThisItem,
const std::function< int()> &  startx = []() { return 0; },
const std::function< int()> &  width = []() { return 50; },
inventory_item_menu_position  position = RIGHT_OF_INFO 
)

Definition at line 2035 of file game.cpp.

2039 {
2040  int cMenu = static_cast<int>( '+' );
2041 
2042  item &oThisItem = *locThisItem;
2043  if( u.has_item( oThisItem ) ) {
2044 #if defined(__ANDROID__)
2045  if( get_option<bool>( "ANDROID_INVENTORY_AUTOADD" ) ) {
2046  add_key_to_quick_shortcuts( oThisItem.invlet, "INVENTORY", false );
2047  }
2048 #endif
2049  const bool bHPR = get_auto_pickup().has_rule( &oThisItem );
2050  std::vector<iteminfo> vThisItem;
2051  std::vector<iteminfo> vDummy;
2052  item_info_data data;
2053  int iScrollPos = 0;
2054  int iScrollHeight = 0;
2055  uilist action_menu;
2056  std::unique_ptr<ui_adaptor> ui;
2057 
2058  bool exit = false;
2059  bool first_execution = true;
2060  static int lang_version = detail::get_current_language_version();
2061  catacurses::window w_info;
2062  do {
2063  //lang check here is needed to redraw the menu when using "Toggle language to English" option
2064  if( first_execution || lang_version != detail::get_current_language_version() ) {
2065 
2066  const hint_rating rate_drop_item = u.get_wielded_item() &&
2069  action_menu.reset();
2070  action_menu.allow_anykey = true;
2071  const auto addentry = [&]( const char key, const std::string & text, const hint_rating hint ) {
2072  // The char is used as retval from the uilist *and* as hotkey.
2073  action_menu.addentry( key, true, key, text );
2074  auto &entry = action_menu.entries.back();
2075  switch( hint ) {
2076  case hint_rating::cant:
2077  entry.text_color = c_light_gray;
2078  break;
2079  case hint_rating::iffy:
2080  entry.text_color = c_light_red;
2081  break;
2082  case hint_rating::good:
2083  entry.text_color = c_light_green;
2084  break;
2085  }
2086  };
2087  addentry( 'a', pgettext( "action", "activate" ), rate_action_use( u, oThisItem ) );
2088  addentry( 'R', pgettext( "action", "read" ), rate_action_read( u, oThisItem ) );
2089  addentry( 'E', pgettext( "action", "eat" ), rate_action_eat( u, oThisItem ) );
2090  addentry( 'W', pgettext( "action", "wear" ), rate_action_wear( u, oThisItem ) );
2091  addentry( 'w', pgettext( "action", "wield" ), rate_action_wield( u, oThisItem ) );
2092  addentry( 't', pgettext( "action", "throw" ), rate_action_wield( u, oThisItem ) );
2093  addentry( 'c', pgettext( "action", "change side" ), rate_action_change_side( u, oThisItem ) );
2094  addentry( 'T', pgettext( "action", "take off" ), rate_action_take_off( u, oThisItem ) );
2095  addentry( 'd', pgettext( "action", "drop" ), rate_drop_item );
2096  addentry( 'U', pgettext( "action", "unload" ), u.rate_action_unload( oThisItem ) );
2097  addentry( 'r', pgettext( "action", "reload" ), u.rate_action_reload( oThisItem ) );
2098  addentry( 'p', pgettext( "action", "part reload" ), u.rate_action_reload( oThisItem ) );
2099  addentry( 'm', pgettext( "action", "mend" ), rate_action_mend( u, oThisItem ) );
2100  addentry( 'D', pgettext( "action", "disassemble" ), rate_action_disassemble( u, oThisItem ) );
2101  if( oThisItem.is_container() && !oThisItem.is_corpse() ) {
2102  addentry( 'i', pgettext( "action", "insert" ), rate_action_insert( u, locThisItem ) );
2103  if( oThisItem.num_item_stacks() > 0 ) {
2104  addentry( 'o', pgettext( "action", "open" ), hint_rating::good );
2105  }
2106  addentry( 'v', pgettext( "action", "pocket settings" ), hint_rating::good );
2107  }
2108 
2109  if( oThisItem.is_favorite ) {
2110  addentry( 'f', pgettext( "action", "unfavorite" ), hint_rating::good );
2111  } else {
2112  addentry( 'f', pgettext( "action", "favorite" ), hint_rating::good );
2113  }
2114 
2115  addentry( 'V', pgettext( "action", "view recipe" ), rate_action_view_recipe( u, oThisItem ) );
2116  addentry( '>', pgettext( "action", "hide contents" ), rate_action_collapse( oThisItem ) );
2117  addentry( '<', pgettext( "action", "show contents" ), rate_action_expand( oThisItem ) );
2118  addentry( '=', pgettext( "action", "reassign" ), hint_rating::good );
2119 
2120  if( bHPR ) {
2121  addentry( '-', _( "Auto pickup" ), hint_rating::iffy );
2122  } else {
2123  addentry( '+', _( "Auto pickup" ), hint_rating::good );
2124  }
2125 
2126  oThisItem.info( true, vThisItem );
2127 
2128  action_menu.w_y_setup = 0;
2129  action_menu.w_x_setup = [&]( const int popup_width ) -> int {
2130  switch( position )
2131  {
2132  default:
2133  case RIGHT_TERMINAL_EDGE:
2134  return 0;
2135  case LEFT_OF_INFO:
2136  return iStartX() - popup_width;
2137  case RIGHT_OF_INFO:
2138  return iStartX() + iWidth();
2139  case LEFT_TERMINAL_EDGE:
2140  return TERMX - popup_width;
2141  }
2142  };
2143  // Filtering isn't needed, the number of entries is manageable.
2144  action_menu.filtering = false;
2145  // Default menu border color is different, this matches the border of the item info window.
2146  action_menu.border_color = BORDER_COLOR;
2147 
2148  data = item_info_data( oThisItem.tname(), oThisItem.type_name(), vThisItem, vDummy, iScrollPos );
2149  data.without_getch = true;
2150 
2151  ui = std::make_unique<ui_adaptor>();
2152  ui->on_screen_resize( [&]( ui_adaptor & ui ) {
2153  w_info = catacurses::newwin( TERMY, iWidth(), point( iStartX(), 0 ) );
2154  iScrollHeight = TERMY - 2;
2155  ui.position_from_window( w_info );
2156  } );
2157  ui->mark_resize();
2158 
2159  ui->on_redraw( [&]( const ui_adaptor & ) {
2160  draw_item_info( w_info, data );
2161  } );
2162 
2163  action_menu.additional_actions = {
2164  { "RIGHT", translation() }
2165  };
2166 
2167  lang_version = detail::get_current_language_version();
2168  first_execution = false;
2169  }
2170 
2171  const int prev_selected = action_menu.selected;
2172  action_menu.query( false );
2173  if( action_menu.ret >= 0 ) {
2174  cMenu = action_menu.ret; /* Remember: hotkey == retval, see addentry above. */
2175  } else if( action_menu.ret == UILIST_UNBOUND && action_menu.ret_act == "RIGHT" ) {
2176  // Simulate KEY_RIGHT == '\n' (confirm currently selected entry) for compatibility with old version.
2177  // TODO: ideally this should be done in the uilist, maybe via a callback.
2178  cMenu = action_menu.ret = action_menu.entries[action_menu.selected].retval;
2179  } else if( action_menu.ret_act == "PAGE_UP" || action_menu.ret_act == "PAGE_DOWN" ) {
2180  cMenu = action_menu.ret_act == "PAGE_UP" ? KEY_PPAGE : KEY_NPAGE;
2181  // Prevent the menu from scrolling with this key. TODO: Ideally the menu
2182  // could be instructed to ignore these two keys instead of scrolling.
2183  action_menu.selected = prev_selected;
2184  action_menu.fselected = prev_selected;
2185  action_menu.vshift = 0;
2186  } else {
2187  cMenu = 0;
2188  }
2189 
2190  if( action_menu.ret != UILIST_WAIT_INPUT && action_menu.ret != UILIST_UNBOUND ) {
2191  exit = true;
2192  ui = nullptr;
2193  }
2194 
2195  switch( cMenu ) {
2196  case 'a': {
2197  contents_change_handler handler;
2198  handler.unseal_pocket_containing( locThisItem );
2199  if( locThisItem.get_item()->type->has_use() &&
2200  !locThisItem.get_item()->item_has_uses_recursive( true ) ) { // NOLINT(bugprone-branch-clone)
2201  // Item has uses and none of its contents (if any) has uses.
2202  avatar_action::use_item( u, locThisItem );
2203  } else if( locThisItem.get_item()->item_has_uses_recursive() ) {
2204  game::item_action_menu( locThisItem );
2205  } else if( locThisItem.get_item()->has_relic_activation() ) {
2206  avatar_action::use_item( u, locThisItem );
2207  } else {
2208  add_msg( m_info, _( "You can't use a %s there." ), locThisItem->tname() );
2209  break;
2210  }
2211  handler.handle_by( u );
2212  break;
2213  }
2214  case 'E':
2215  if( !locThisItem.get_item()->is_container() ) {
2216  avatar_action::eat( u, locThisItem );
2217  } else {
2219  }
2220  break;
2221  case 'W': {
2222  contents_change_handler handler;
2223  handler.unseal_pocket_containing( locThisItem );
2224  u.wear( locThisItem );
2225  handler.handle_by( u );
2226  break;
2227  }
2228  case 'w':
2229  if( u.can_wield( *locThisItem ).success() ) {
2230  contents_change_handler handler;
2231  handler.unseal_pocket_containing( locThisItem );
2232  wield( locThisItem );
2233  handler.handle_by( u );
2234  } else {
2235  add_msg( m_info, "%s", u.can_wield( *locThisItem ).c_str() );
2236  }
2237  break;
2238  case 't': {
2239  contents_change_handler handler;
2240  handler.unseal_pocket_containing( locThisItem );
2241  avatar_action::plthrow( u, locThisItem );
2242  handler.handle_by( u );
2243  break;
2244  }
2245  case 'c':
2246  u.change_side( locThisItem );
2247  break;
2248  case 'T':
2249  u.takeoff( locThisItem );
2250  break;
2251  case 'd':
2252  u.drop( locThisItem, u.pos() );
2253  break;
2254  case 'U':
2255  u.unload( locThisItem );
2256  break;
2257  case 'r':
2258  reload( locThisItem );
2259  break;
2260  case 'p':
2261  reload( locThisItem, true );
2262  break;
2263  case 'm':
2264  avatar_action::mend( u, locThisItem );
2265  break;
2266  case 'R':
2267  u.read( locThisItem );
2268  break;
2269  case 'D':
2270  u.disassemble( locThisItem, false );
2271  break;
2272  case 'f':
2273  oThisItem.is_favorite = !oThisItem.is_favorite;
2274  if( locThisItem.has_parent() ) {
2275  item_location parent = locThisItem.parent_item();
2276  item_pocket *const pocket = locThisItem.parent_pocket();
2277  if( pocket ) {
2278  pocket->restack();
2279  } else {
2280  debugmsg( "parent container does not contain item" );
2281  }
2282  }
2283  break;
2284  case 'v':
2285  if( oThisItem.is_container() ) {
2286  oThisItem.favorite_settings_menu();
2287  }
2288  break;
2289  case 'V': {
2290  int is_recipe = 0;
2291  std::string this_itype = oThisItem.typeId().str();
2292  if( oThisItem.is_craft() ) {
2293  this_itype = oThisItem.get_making().ident().str();
2294  is_recipe = 1;
2295  }
2296  player_activity recipe_act = player_activity( ACT_VIEW_RECIPE, 0, is_recipe, 0, this_itype );
2297  u.assign_activity( recipe_act );
2298  break;
2299  }
2300  case 'i':
2301  if( oThisItem.is_container() ) {
2302  game_menus::inv::insert_items( u, locThisItem );
2303  }
2304  break;
2305  case 'o':
2306  if( oThisItem.is_container() && oThisItem.num_item_stacks() > 0 ) {
2307  game_menus::inv::common( locThisItem, u );
2308  }
2309  break;
2310  case '=':
2311  game_menus::inv::reassign_letter( u, oThisItem );
2312  break;
2313  case KEY_PPAGE:
2314  iScrollPos -= iScrollHeight;
2315  if( ui ) {
2316  ui->invalidate_ui();
2317  }
2318  break;
2319  case KEY_NPAGE:
2320  iScrollPos += iScrollHeight;
2321  if( ui ) {
2322  ui->invalidate_ui();
2323  }
2324  break;
2325  case '+':
2326  if( !bHPR ) {
2327  get_auto_pickup().add_rule( &oThisItem, true );
2328  add_msg( m_info, _( "'%s' added to character pickup rules." ), oThisItem.tname( 1,
2329  false ) );
2330  }
2331  break;
2332  case '-':
2333  if( bHPR ) {
2334  get_auto_pickup().remove_rule( &oThisItem );
2335  add_msg( m_info, _( "'%s' removed from character pickup rules." ), oThisItem.tname( 1,
2336  false ) );
2337  }
2338  break;
2339  case '<':
2340  case '>':
2341  for( item_pocket *pocket : oThisItem.get_all_standard_pockets() ) {
2342  pocket->settings.set_collapse( cMenu == '>' );
2343  }
2344  break;
2345  default:
2346  break;
2347  }
2348  } while( !exit );
2349  }
2350  return cMenu;
2351 }
ret_val< void > can_wield(const item &it) const
Check player capable of wielding an item.
Definition: character.cpp:7836
bool unload(item_location &loc, bool bypass_activity=false, const item_location &new_container=item_location::nowhere)
Unload item.
hint_rating rate_action_reload(const item &it) const
Same as Character::can_reload, but checks for attached gunmods as well.
bool takeoff(item_location loc, std::list< item > *res=nullptr)
Takes off an item, returning false on fail.
bool change_side(item &it, bool interactive=true)
Swap side on which item is worn; returns false on fail.
hint_rating rate_action_unload(const item &it) const
Whether a tool or a gun can be unloaded.
std::optional< std::list< item >::iterator > wear(int pos, bool interactive=true)
Wear item; returns false on fail.
void remove_rule(const item *it)
void add_rule(const item *it, bool include)
bool has_rule(const item *it)
bool read(item_location &book, item_location ereader={})
Handles reading effects and returns true if activity started.
Definition: avatar.cpp:432
Records a batch of unsealed containers and handles spilling at once.
void unseal_pocket_containing(const item_location &loc)
Unseal the pocket containing loc and add loc's parent to the list.
void handle_by(Character &guy)
Let the guy handle any container that needs spilling.
void reload(item_location &loc, bool prompt=false, bool empty=true)
Definition: game.cpp:9936
item * get_item()
Gets the selected item or nullptr.
item_location parent_item() const
returns the parent item, or an invalid location if it has no parent
item_pocket * parent_pocket() const
bool has_parent() const
true if this item location can and does have a parent
void set_collapse(bool)
Flag to show or hide the pocket contents in 'i'nventory screen.
void restack()
stacks like items inside the pocket
favorite_settings settings
Definition: item_pocket.h:387
bool is_favorite
Definition: item.h:3213
std::vector< const item_pocket * > get_all_standard_pockets() const
Definition: item.cpp:9711
itype_id typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:11850
bool item_has_uses_recursive(bool contents_only=false) const
True if item and its contents have any uses.
Definition: item_action.cpp:78
std::string info(bool showtext=false) const
Return all the information about the item and its type.
Definition: item.cpp:1953
const recipe & get_making() const
Get the stored recipe for in progress crafts.
Definition: item.cpp:14758
bool is_craft() const
Definition: item.cpp:9930
void favorite_settings_menu()
Open a menu for the player to set pocket favorite settings for the pockets in this item_contents.
Definition: item.cpp:15180
size_t num_item_stacks() const
returns the number of items stacks in contents each item that is not count_by_charges,...
Definition: item.cpp:15165
std::string type_name(unsigned int quantity=1, bool use_variant=true, bool use_cond_name=true, bool use_corpse=true) const
Name of the item type (not the item), with proper plural.
Definition: item.cpp:14449
const itype * type
Definition: item.h:3074
bool has_relic_activation() const
Definition: item.cpp:9989
char invlet
Definition: item.h:3211
const recipe_id & ident() const
Definition: recipe.h:155
const char * c_str() const
Definition: ret_val.h:21
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:260
Class for storing translation context and raw string for deferred translation.
Definition: translation.h:18
nc_color border_color
Definition: ui.h:427
bool filtering
Definition: ui.h:453
pos_scalar w_x_setup
Definition: ui.h:436
void reset()
cleanup
Definition: ui.cpp:1204
std::string ret_act
Definition: ui.h:523
int fselected
Definition: ui.h:490
std::vector< std::pair< std::string, translation > > additional_actions
Definition: ui.h:425
int selected
Definition: ui.h:526
bool allow_anykey
Definition: ui.h:459
int vshift
Definition: ui.h:488
const flag_id flag_NO_UNWIELD("NO_UNWIELD")
static hint_rating rate_action_collapse(const item &it)
Definition: game.cpp:1911
static hint_rating rate_action_disassemble(avatar &you, const item &it)
Definition: game.cpp:1831
static hint_rating rate_action_use(const avatar &you, const item &it)
Definition: game.cpp:1963
static hint_rating rate_action_eat(const avatar &you, const item &it)
Definition: game.cpp:1878
static hint_rating rate_action_mend(const avatar &, const item &it)
Definition: game.cpp:1931
static hint_rating rate_action_wield(const avatar &you, const item &it)
Definition: game.cpp:2008
static hint_rating rate_action_read(const avatar &you, const item &it)
Definition: game.cpp:1940
static hint_rating rate_action_expand(const item &it)
Definition: game.cpp:1921
static const activity_id ACT_VIEW_RECIPE("ACT_VIEW_RECIPE")
static hint_rating rate_action_change_side(const avatar &you, const item &it)
Definition: game.cpp:1822
static hint_rating rate_action_take_off(const avatar &you, const item &it)
Definition: game.cpp:1950
static hint_rating rate_action_wear(const avatar &you, const item &it)
Definition: game.cpp:1995
static hint_rating rate_action_view_recipe(avatar &you, const item &it)
Definition: game.cpp:1845
constexpr int KEY_NPAGE
Definition: input.h:60
constexpr int KEY_PPAGE
Definition: input.h:61
hint_rating
Hint value used for item examination screen and filtering items by action.
Definition: item.h:3241
@ iffy
Item permits this action, but circumstances don't.
@ cant
Item does not permit this action.
void eat(avatar &you, item_location &loc)
Eat food or fuel 'E' (or 'a')
int get_current_language_version()
void reassign_letter(avatar &you, item &it)
input_event draw_item_info(const int iLeft, const int iWidth, const int iTop, const int iHeight, item_info_data &data)
Definition: output.cpp:962
#define BORDER_COLOR
Definition: output.h:98
bool without_getch
Definition: output.h:546
bool has_use() const
Definition: itype.cpp:159
const int UILIST_UNBOUND
Definition: ui.h:34
const int UILIST_WAIT_INPUT
Definition: ui.h:33

References _, ACT_VIEW_RECIPE, add_msg(), auto_pickup::player_settings::add_rule(), uilist::addentry(), uilist::additional_actions, uilist::allow_anykey, Character::assign_activity(), BORDER_COLOR, uilist::border_color, c_light_gray, c_light_green, c_light_red, ret_val_common::c_str(), Character::can_wield(), cant, Character::change_side(), game_menus::inv::common(), game_menus::inv::consume(), debugmsg, Character::disassemble(), draw_item_info(), Character::drop(), avatar_action::eat(), avatar_action::eat_or_use(), uilist::entries, item::favorite_settings_menu(), uilist::filtering, flag_NO_UNWIELD, uilist::fselected, item::get_all_standard_pockets(), get_auto_pickup(), detail::get_current_language_version(), item_location::get_item(), item::get_making(), Character::get_wielded_item(), good, contents_change_handler::handle_by(), item::has_flag(), visitable::has_item(), item_location::has_parent(), item::has_relic_activation(), auto_pickup::player_settings::has_rule(), itype::has_use(), recipe::ident(), iffy, item::info(), game_menus::inv::insert_items(), item::invlet, item::is_container(), item::is_corpse(), item::is_craft(), item::is_favorite, item_action_menu(), item::item_has_uses_recursive(), KEY_NPAGE, KEY_PPAGE, LEFT_OF_INFO, LEFT_TERMINAL_EDGE, m_info, avatar_action::mend(), catacurses::newwin(), item::num_item_stacks(), item_location::parent_item(), item_location::parent_pocket(), pgettext, avatar_action::plthrow(), point, Creature::pos(), uilist::query(), rate_action_change_side(), rate_action_collapse(), rate_action_disassemble(), rate_action_eat(), rate_action_expand(), rate_action_insert(), rate_action_mend(), rate_action_read(), Character::rate_action_reload(), rate_action_take_off(), Character::rate_action_unload(), rate_action_use(), rate_action_view_recipe(), rate_action_wear(), rate_action_wield(), avatar::read(), game_menus::inv::reassign_letter(), reload(), auto_pickup::player_settings::remove_rule(), uilist::reset(), item_pocket::restack(), uilist::ret, uilist::ret_act, RIGHT_OF_INFO, RIGHT_TERMINAL_EDGE, uilist::selected, string_id< T >::str(), ret_val_common::success(), Character::takeoff(), TERMX, TERMY, item::tname(), item::type, item::type_name(), item::typeId(), u, UILIST_UNBOUND, UILIST_WAIT_INPUT, Character::unload(), contents_change_handler::unseal_pocket_containing(), avatar_action::use_item(), uilist::vshift, uilist::w_x_setup, uilist::w_y_setup, Character::wear(), wield(), and item_info_data::without_getch.

◆ is_core_data_loaded()

bool game::is_core_data_loaded ( ) const

Returns whether the core data is currently loaded.

Definition at line 575 of file game.cpp.

576 {
578 }
bool is_data_finalized() const
Returns whether the data is finalized and ready to be utilized.
Definition: init.h:174

References DynamicDataLoader::get_instance(), and DynamicDataLoader::is_data_finalized().

◆ is_dangerous_tile()

bool game::is_dangerous_tile ( const tripoint dest_loc) const

Definition at line 10408 of file game.cpp.

10409 {
10410  return !get_dangerous_tile( dest_loc ).empty();
10411 }

References get_dangerous_tile().

Referenced by safe_route_to(), and walk_move().

◆ is_empty() [1/2]

bool game::is_empty ( const tripoint p)

Returns true if there is no player, NPC, or monster on the tile and move_cost > 0.

Definition at line 5506 of file game.cpp.

5507 {
5508  return ( m.passable( p ) || m.has_flag( ter_furn_flag::TFLAG_LIQUID, p ) ) &&
5509  get_creature_tracker().creature_at( p ) == nullptr;
5510 }

References creature_tracker::creature_at(), get_creature_tracker, map::has_flag(), m, map::passable(), and TFLAG_LIQUID.

Referenced by can_move_furniture(), is_empty(), and place_player().

◆ is_empty() [2/2]

bool game::is_empty ( const tripoint_bub_ms p)

Definition at line 5512 of file game.cpp.

5513 {
5514  return is_empty( p.raw() );
5515 }

References is_empty(), and coords::coord_point_mut< Point, Subpoint, InBounds >::raw().

◆ is_game_over()

bool game::is_game_over ( )
private

Definition at line 2734 of file game.cpp.

2735 {
2736  if( uquit == QUIT_DIED || uquit == QUIT_WATCH ) {
2738  }
2739  if( uquit == QUIT_WATCH ) {
2740  // deny player movement and dodging
2741  u.set_moves( 0 );
2742  // prevent pain from updating
2743  u.set_pain( 0 );
2744  // prevent dodging
2745  u.set_dodges_left( 0 );
2746  return false;
2747  }
2748  if( uquit == QUIT_DIED ) {
2749  if( u.in_vehicle ) {
2750  m.unboard_vehicle( u.pos() );
2751  }
2752  u.place_corpse();
2753  return true;
2754  }
2755  if( uquit == QUIT_SUICIDE ) {
2756  bury_screen();
2757  if( u.in_vehicle ) {
2758  m.unboard_vehicle( u.pos() );
2759  }
2760  return true;
2761  }
2762  if( uquit != QUIT_NO ) {
2763  return true;
2764  }
2765  // is_dead_state() already checks hp_torso && hp_head, no need to for loop it
2766  if( u.is_dead_state() ) {
2768  if( !u.is_dead_state() ) {
2769  return false;
2770  }
2771  bury_screen();
2773  if( !u.is_dead_state() ) {
2774  return false;
2775  }
2777  if( get_option<std::string>( "DEATHCAM" ) == "always" ) {
2778  uquit = QUIT_WATCH;
2779  } else if( get_option<std::string>( "DEATHCAM" ) == "ask" ) {
2780  uquit = query_yn( _( "Watch the last moments of your life…?" ) ) ?
2782  } else if( get_option<std::string>( "DEATHCAM" ) == "never" ) {
2783  uquit = QUIT_DIED;
2784  } else {
2785  // Something funky happened here, just die.
2786  dbg( D_ERROR ) << "no deathcam option given to options, defaulting to QUIT_DIED";
2787  uquit = QUIT_DIED;
2788  }
2789  return is_game_over();
2790  }
2791  return false;
2792 }
void set_dodges_left(int dodges)
Definition: character.cpp:1170
void set_pain(int npain) override
Sets new intensity of pain an reacts to it.
void bury_screen() const
Definition: game.cpp:2794
bool is_game_over()
Definition: game.cpp:2734
@ D_ERROR
Definition: debug.h:142
#define dbg(x)
Definition: game.cpp:373
void deactivate()
Definition: messages.cpp:470
void prevent_death()
Run all prevent death eocs.
void avatar_death()
Run all avatar death eocs.

References _, effect_on_conditions::avatar_death(), avatar_dies, bury_screen(), D_ERROR, dbg, Messages::deactivate(), events(), Character::in_vehicle, Character::is_dead_state(), m, Character::place_corpse(), Creature::pos(), effect_on_conditions::prevent_death(), query_yn(), QUIT_DIED, QUIT_NO, QUIT_SUICIDE, QUIT_WATCH, event_bus::send(), Character::set_dodges_left(), Creature::set_moves(), Character::set_pain(), u, map::unboard_vehicle(), and uquit.

◆ is_hostile_nearby()

Creature * game::is_hostile_nearby ( )

Definition at line 4473 of file game.cpp.

4474 {
4475  int distance = ( get_option<int>( "SAFEMODEPROXIMITY" ) <= 0 ) ? MAX_VIEW_DISTANCE :
4476  get_option<int>( "SAFEMODEPROXIMITY" );
4477  return is_hostile_within( distance );
4478 }
Creature * is_hostile_within(int distance, bool dangerous=false)
Checks if there's a hostile creature within given distance.
Definition: game.cpp:4485

References is_hostile_within(), and MAX_VIEW_DISTANCE.

◆ is_hostile_very_close()

Creature * game::is_hostile_very_close ( bool  dangerous = false)

Definition at line 4480 of file game.cpp.

4481 {
4482  return is_hostile_within( DANGEROUS_PROXIMITY, dangerous );
4483 }
static constexpr int DANGEROUS_PROXIMITY
Definition: game.cpp:375

References DANGEROUS_PROXIMITY, and is_hostile_within().

Referenced by butcher().

◆ is_hostile_within()

Creature * game::is_hostile_within ( int  distance,
bool  dangerous = false 
)
private

Checks if there's a hostile creature within given distance.

Parameters
dangerousIf true, makes additional checks for monsters with ranged attack capabilities within distance OR if there's a route from monster to player, and returns this particular monster.
Returns
Hostile creature within given distance.

Definition at line 4485 of file game.cpp.

4486 {
4487  for( Creature *&critter : u.get_visible_creatures( distance ) ) {
4488  if( u.attitude_to( *critter ) == Creature::Attitude::HOSTILE ) {
4489  if( dangerous ) {
4490  if( critter->is_ranged_attacker() ) {
4491  return critter;
4492  }
4493 
4494  const pathfinding_settings pf_settings = pathfinding_settings{ 8, distance, distance * 2, 4, true, true, false, true, false, false };
4495  static const std::unordered_set<tripoint> path_avoid = {};
4496 
4497  if( !get_map().route( u.pos(), critter->pos(), pf_settings, path_avoid ).empty() ) {
4498  return critter;
4499  }
4500  continue;
4501  }
4502  return critter;
4503  }
4504  }
4505 
4506  return nullptr;
4507 }
Attitude attitude_to(const Creature &other) const override
Attitude (of this creature) towards another creature.
std::vector< Creature * > get_visible_creatures(int range) const
Returns all creatures that this player can see and that are in the given range.

References Character::attitude_to(), get_map, Character::get_visible_creatures(), Creature::HOSTILE, Creature::pos(), and u.

Referenced by is_hostile_nearby(), and is_hostile_very_close().

◆ is_in_dangerous_field()

field_entry * game::is_in_dangerous_field ( )

Definition at line 4509 of file game.cpp.

4510 {
4511  map &here = get_map();
4512  for( std::pair<const field_type_id, field_entry> &field : here.field_at( u.pos() ) ) {
4513  if( u.is_dangerous_field( field.second ) ) {
4514  return &field.second;
4515  }
4516  }
4517 
4518  return nullptr;
4519 }

References map::field_at(), get_map, Creature::is_dangerous_field(), Creature::pos(), and u.

◆ is_in_sunlight()

bool game::is_in_sunlight ( const tripoint p)

Returns true if p is outdoors and it is sunny.

Definition at line 5517 of file game.cpp.

5518 {
5519  return !is_sheltered( p ) &&
5521 }
friend weather_manager & get_weather()
Definition: game.cpp:13866
bool is_sheltered(const tripoint &p)
Returns true if p is indoors, underground, or in a car.
Definition: game.cpp:5523
float incident_sun_irradiance(const weather_type_id &wtype, const time_point &t)
Definition: weather.cpp:143
constexpr float minimal
Definition: weather.h:59

References get_weather, incident_sun_irradiance(), is_sheltered(), irradiance::minimal, and calendar::turn.

◆ is_in_viewport()

bool game::is_in_viewport ( const tripoint p,
int  margin = 0 
) const

Definition at line 4122 of file game.cpp.

4123 {
4124  const tripoint diff( u.pos() + u.view_offset - p );
4125 
4126  return ( std::abs( diff.x ) <= getmaxx( w_terrain ) / 2 - margin ) &&
4127  ( std::abs( diff.y ) <= getmaxy( w_terrain ) / 2 - margin );
4128 }

References abs(), catacurses::getmaxx(), catacurses::getmaxy(), Creature::pos(), u, Character::view_offset, w_terrain, tripoint::x, and tripoint::y.

◆ is_sheltered()

bool game::is_sheltered ( const tripoint p)

Returns true if p is indoors, underground, or in a car.

Definition at line 5523 of file game.cpp.

5524 {
5525  const optional_vpart_position vp = m.veh_at( p );
5526  bool is_inside = vp && vp->is_inside();
5527 
5528  return !m.is_outside( p ) ||
5529  p.z < 0 ||
5530  is_inside;
5531 }

References map::is_outside(), m, map::veh_at(), and tripoint::z.

Referenced by is_in_sunlight().

◆ is_tileset_isometric()

bool game::is_tileset_isometric ( ) const

Definition at line 688 of file game.cpp.

689 {
690 #if defined(TILES)
691  return use_tiles && tilecontext && tilecontext->is_isometric();
692 #else
693  return false;
694 #endif
695 }

References use_tiles.

◆ is_zones_manager_open()

bool game::is_zones_manager_open ( ) const

Definition at line 6857 of file game.cpp.

6858 {
6859  return zones_manager_open;
6860 }
bool zones_manager_open
Is Zone manager open or not - changes graphics of some zone tiles.
Definition: game.h:1188

References zones_manager_open.

◆ item_action_menu()

void game::item_action_menu ( item_location  loc = item_location())
private

Definition at line 249 of file item_action.cpp.

250 {
252  const action_map &item_actions = gen.get_item_action_map();
253  std::vector<item *> pseudos;
254  bool use_player_inventory = false;
255  if( !loc ) {
256  use_player_inventory = true;
257  // Ugly const_cast because the menu needs non-const pointers
258  std::vector<const item *> pseudo_items = get_player_character().get_pseudo_items();
259  pseudos.reserve( pseudo_items.size() );
260  for( const item *pseudo : pseudo_items ) {
261  pseudos.push_back( const_cast<item *>( pseudo ) );
262  }
263  } else {
264  if( loc.get_item()->type->has_use() ) {
265  pseudos.push_back( const_cast< item * >( loc.get_item() ) );
266  }
267  loc.get_item()->visit_contents( [&pseudos]( item * node, item * ) {
268  if( node->type->use_methods.empty() ) {
269  return VisitResponse::NEXT;
270  }
271  pseudos.push_back( const_cast<item *>( node ) );
272  return VisitResponse::NEXT;
273  } );
274  }
275  item_action_map iactions = gen.map_actions_to_items( u, pseudos, use_player_inventory );
276  if( iactions.empty() ) {
277  popup( _( "You don't have any items with registered uses" ) );
278  }
279 
280  uilist kmenu;
281  kmenu.desc_enabled = true;
282  kmenu.text = _( "Execute which action?" );
283  kmenu.input_category = "ITEM_ACTIONS";
284  input_context ctxt( "ITEM_ACTIONS", keyboard_mode::keycode );
285  for( const std::pair<const item_action_id, item_action> &id : item_actions ) {
286  ctxt.register_action( id.first, id.second.name );
287  kmenu.additional_actions.emplace_back( id.first, id.second.name );
288  }
289  actmenu_cb callback( item_actions );
290  kmenu.callback = &callback;
291  int num = 0;
292 
293  const auto assigned_action = [&iactions]( const item_action_id & action ) {
294  return iactions.find( action ) != iactions.end();
295  };
296 
297  std::vector<std::tuple<item_action_id, std::string, std::string, std::string>> menu_items;
298  // Sorts menu items by action.
299  using Iter = decltype( menu_items )::iterator;
300  const auto sort_menu = []( Iter from, Iter to ) {
301  std::sort( from, to, []( const auto & lhs, const auto & rhs ) {
302  return std::get<1>( lhs ).compare( std::get<1>( rhs ) ) < 0;
303  } );
304  };
305  // Add mapped actions to the menu vector.
306  std::transform( iactions.begin(), iactions.end(), std::back_inserter( menu_items ),
307  []( const std::pair<item_action_id, item *> &elem ) {
308  std::string ss = elem.second->display_name();
309  if( elem.second->ammo_required() ) {
310 
311  if( elem.second->has_flag( flag_USES_BIONIC_POWER ) ) {
312  ss += string_format( "(%d kJ)", elem.second->ammo_required() );
313  } else {
314  auto iter = elem.second->type->ammo_scale.find( elem.first );
315  ss += string_format( "(-%d)", elem.second->ammo_required() * ( iter ==
316  elem.second->type->ammo_scale.end() ? 1 : iter->second ) );
317  }
318 
319  }
320 
321  const use_function *method = elem.second->get_use( elem.first );
322  if( method ) {
323  return std::make_tuple( method->get_type(), method->get_name(), ss, method->get_description() );
324  } else {
325  return std::make_tuple( errstring, std::string( "NO USE FUNCTION" ), ss, std::string() );
326  }
327  } );
328  // Sort mapped actions.
329  sort_menu( menu_items.begin(), menu_items.end() );
330  if( !loc ) {
331  // Add unmapped but binded actions to the menu vector.
332  for( const auto &elem : item_actions ) {
333  if( key_bound_to( ctxt, elem.first ).has_value() && !assigned_action( elem.first ) ) {
334  menu_items.emplace_back( elem.first, gen.get_action_name( elem.first ), "-", std::string() );
335  }
336  }
337  }
338  // Sort unmapped actions.
339  auto iter = menu_items.begin();
340  std::advance( iter, iactions.size() );
341  sort_menu( iter, menu_items.end() );
342  // Determine max lengths, to print the menu nicely.
343  std::pair<int, int> max_len;
344  for( const auto &elem : menu_items ) {
345  max_len.first = std::max( max_len.first, utf8_width( std::get<1>( elem ), true ) );
346  max_len.second = std::max( max_len.second, utf8_width( std::get<2>( elem ), true ) );
347  }
348  // Fill the menu.
349  for( const auto &elem : menu_items ) {
350  std::string ss;
351  ss += std::get<1>( elem );
352  ss += std::string( max_len.first - utf8_width( std::get<1>( elem ), true ), ' ' );
353  ss += std::string( 4, ' ' );
354 
355  ss += std::get<2>( elem );
356  ss += std::string( max_len.second - utf8_width( std::get<2>( elem ), true ), ' ' );
357 
358  const std::optional<input_event> bind = key_bound_to( ctxt, std::get<0>( elem ) );
359  const bool enabled = assigned_action( std::get<0>( elem ) );
360  const std::string desc = std::get<3>( elem ) ;
361 
362  kmenu.addentry_desc( num, enabled, bind, ss, desc );
363  num++;
364  }
365 
366  kmenu.footer_text = string_format( _( "[<color_yellow>%s</color>] keybindings" ),
367  ctxt.get_desc( "HELP_KEYBINDINGS" ) );
368 
369  kmenu.query();
370  if( kmenu.ret < 0 || kmenu.ret >= static_cast<int>( iactions.size() ) ) {
371  return;
372  }
373 
374  const item_action_id action = std::get<0>( menu_items[kmenu.ret] );
375  item *it = iactions[action];
376 
377  u.invoke_item( it, action );
378 
379  u.inv->restack( u );
380  u.inv->unsort();
381 }
std::vector< const item * > get_pseudo_items() const
Definition: character.cpp:2666
pimpl< inventory > inv
Definition: character.h:2712
bool invoke_item(item *, const tripoint &pt, int pre_obtain_moves) override
Asks how to use the item (if it has more than one use_method) and uses it.
Definition: avatar.cpp:1482
std::string get_action_name(const item_action_id &id) const
static item_action_generator & generator()
Definition: item_action.h:33
item_action_map map_actions_to_items(Character &you) const
const action_map & get_item_action_map() const
Definition: item_action.h:63
VisitResponse visit_contents(const std::function< VisitResponse(item *, item *)> &func, item *parent=nullptr)
NOTE: upon expansion, this may need to be filtered by type enum depending on accessibility.
Definition: visitable.cpp:366
bool desc_enabled
Definition: ui.h:451
std::string input_category
Definition: ui.h:424
std::string footer_text
Definition: ui.h:421
void addentry_desc(const std::string &txt, const std::string &desc)
Definition: ui.cpp:1227
static std::optional< input_event > key_bound_to(const input_context &ctxt, const item_action_id &act)
Definition: item_action.cpp:41
std::string item_action_id
Definition: item_action.h:17
std::map< item_action_id, item_action > action_map
Definition: item_action.h:19
std::map< item_action_id, item * > item_action_map
Definition: item_action.h:18
std::map< std::string, use_function > use_methods
Actions an instance can perform (if any) indexed by action type.
Definition: itype.h:1312

References _, action, uilist::additional_actions, uilist::callback, uilist::desc_enabled, item_action_generator::generator(), item_location::get_item(), item_action_generator::get_item_action_map(), get_player_character, Character::get_pseudo_items(), itype::has_use(), uilist::input_category, keycode, item_action_generator::map_actions_to_items(), NEXT, popup(), input_context::register_action(), second, uilist::text, item::type, u, itype::use_methods, and item::visit_contents().

Referenced by do_regular_action(), and inventory_item_menu().

◆ knockback() [1/2]

void game::knockback ( const tripoint s,
const tripoint t,
int  force,
int  stun,
int  dam_mult 
)

Definition at line 4853 of file game.cpp.

4854 {
4855  std::vector<tripoint> traj;
4856  traj.clear();
4857  traj = line_to( s, t, 0, 0 );
4858  traj.insert( traj.begin(), s ); // how annoying, line_to() doesn't include the originating point!
4859  traj = continue_line( traj, force );
4860  traj.insert( traj.begin(), t ); // how annoying, continue_line() doesn't either!
4861 
4862  knockback( traj, stun, dam_mult );
4863 }
std::vector< coords::coord_point< Point, Origin, Scale, LhsInBounds &&RhsInBounds > > line_to(const coords::coord_point< Point, Origin, Scale, LhsInBounds > &loc1, const coords::coord_point< Point, Origin, Scale, RhsInBounds > &loc2)
Definition: coordinates.h:798
std::vector< tripoint > continue_line(const std::vector< tripoint > &line, const int distance)
Definition: line.cpp:380

References continue_line(), force, and line_to().

Referenced by forced_door_closing(), and knockback().

◆ knockback() [2/2]

void game::knockback ( std::vector< tripoint > &  traj,
int  stun,
int  dam_mult 
)

Definition at line 4869 of file game.cpp.

4870 {
4871  // TODO: make the force parameter actually do something.
4872  // the header file says higher force causes more damage.
4873  // perhaps that is what it should do?
4874  tripoint tp = traj.front();
4875  creature_tracker &creatures = get_creature_tracker();
4876  if( !creatures.creature_at( tp ) ) {
4877  debugmsg( _( "Nothing at (%d,%d,%d) to knockback!" ), tp.x, tp.y, tp.z );
4878  return;
4879  }
4880  std::size_t force_remaining = traj.size();
4881  if( monster *const targ = creatures.creature_at<monster>( tp, true ) ) {
4882  if( stun > 0 ) {
4883  targ->add_effect( effect_stunned, 1_turns * stun );
4884  add_msg( _( "%s was stunned!" ), targ->name() );
4885  }
4886  for( size_t i = 1; i < traj.size(); i++ ) {
4887  if( m.impassable( traj[i].xy() ) ) {
4888  targ->setpos( traj[i - 1] );
4889  force_remaining = traj.size() - i;
4890  if( stun != 0 ) {
4891  targ->add_effect( effect_stunned, 1_turns * force_remaining );
4892  add_msg( _( "%s was stunned!" ), targ->name() );
4893  add_msg( _( "%s slammed into an obstacle!" ), targ->name() );
4894  targ->apply_damage( nullptr, bodypart_id( "torso" ), dam_mult * force_remaining );
4895  targ->check_dead_state();
4896  }
4897  m.bash( traj[i], 2 * dam_mult * force_remaining );
4898  break;
4899  } else if( creatures.creature_at( traj[i] ) ) {
4900  targ->setpos( traj[i - 1] );
4901  force_remaining = traj.size() - i;
4902  if( stun != 0 ) {
4903  targ->add_effect( effect_stunned, 1_turns * force_remaining );
4904  add_msg( _( "%s was stunned!" ), targ->name() );
4905  }
4906  traj.erase( traj.begin(), traj.begin() + i );
4907  if( creatures.creature_at<monster>( traj.front() ) ) {
4908  add_msg( _( "%s collided with something else and sent it flying!" ),
4909  targ->name() );
4910  } else if( npc *const guy = creatures.creature_at<npc>( traj.front() ) ) {
4911  if( guy->male ) {
4912  add_msg( _( "%s collided with someone else and sent him flying!" ),
4913  targ->name() );
4914  } else {
4915  add_msg( _( "%s collided with someone else and sent her flying!" ),
4916  targ->name() );
4917  }
4918  } else if( u.pos() == traj.front() ) {
4919  add_msg( m_bad, _( "%s collided with you and sent you flying!" ), targ->name() );
4920  }
4921  knockback( traj, stun, dam_mult );
4922  break;
4923  }
4924  targ->setpos( traj[i] );
4925  if( m.has_flag( ter_furn_flag::TFLAG_LIQUID, targ->pos() ) && !targ->can_drown() &&
4926  !targ->is_dead() ) {
4927  targ->die( nullptr );
4928  if( u.sees( *targ ) ) {
4929  add_msg( _( "The %s drowns!" ), targ->name() );
4930  }
4931  }
4932  if( !m.has_flag( ter_furn_flag::TFLAG_LIQUID, targ->pos() ) && targ->has_flag( mon_flag_AQUATIC ) &&
4933  !targ->is_dead() ) {
4934  targ->die( nullptr );
4935  if( u.sees( *targ ) ) {
4936  add_msg( _( "The %s flops around and dies!" ), targ->name() );
4937  }
4938  }
4939  }
4940  } else if( npc *const targ = creatures.creature_at<npc>( tp ) ) {
4941  if( stun > 0 ) {
4942  targ->add_effect( effect_stunned, 1_turns * stun );
4943  add_msg( _( "%s was stunned!" ), targ->get_name() );
4944  }
4945  for( size_t i = 1; i < traj.size(); i++ ) {
4946  if( m.impassable( traj[i].xy() ) ) { // oops, we hit a wall!
4947  targ->setpos( traj[i - 1] );
4948  force_remaining = traj.size() - i;
4949  if( stun != 0 ) {
4950  targ->add_effect( effect_stunned, 1_turns * force_remaining );
4951  if( targ->has_effect( effect_stunned ) ) {
4952  add_msg( _( "%s was stunned!" ), targ->get_name() );
4953  }
4954 
4955  std::array<bodypart_id, 8> bps = {{
4956  bodypart_id( "head" ),
4957  bodypart_id( "arm_l" ), bodypart_id( "arm_r" ),
4958  bodypart_id( "hand_l" ), bodypart_id( "hand_r" ),
4959  bodypart_id( "torso" ),
4960  bodypart_id( "leg_l" ), bodypart_id( "leg_r" )
4961  }
4962  };
4963  for( const bodypart_id &bp : bps ) {
4964  if( one_in( 2 ) ) {
4965  targ->deal_damage( nullptr, bp, damage_instance( damage_bash, force_remaining * dam_mult ) );
4966  }
4967  }
4968  targ->check_dead_state();
4969  }
4970  m.bash( traj[i], 2 * dam_mult * force_remaining );
4971  break;
4972  } else if( creatures.creature_at( traj[i] ) ) {
4973  targ->setpos( traj[i - 1] );
4974  force_remaining = traj.size() - i;
4975  if( stun != 0 ) {
4976  add_msg( _( "%s was stunned!" ), targ->get_name() );
4977  targ->add_effect( effect_stunned, 1_turns * force_remaining );
4978  }
4979  traj.erase( traj.begin(), traj.begin() + i );
4980  const tripoint &traj_front = traj.front();
4981  if( creatures.creature_at<monster>( traj_front ) ) {
4982  add_msg( _( "%s collided with something else and sent it flying!" ),
4983  targ->get_name() );
4984  } else if( npc *const guy = creatures.creature_at<npc>( traj_front ) ) {
4985  if( guy->male ) {
4986  add_msg( _( "%s collided with someone else and sent him flying!" ),
4987  targ->get_name() );
4988  } else {
4989  add_msg( _( "%s collided with someone else and sent her flying!" ),
4990  targ->get_name() );
4991  }
4992  } else if( u.posx() == traj_front.x && u.posy() == traj_front.y &&
4994  add_msg( _( "%s collided with you, and barely dislodges your tentacles!" ), targ->get_name() );
4995  } else if( u.posx() == traj_front.x && u.posy() == traj_front.y ) {
4996  add_msg( m_bad, _( "%s collided with you and sent you flying!" ), targ->get_name() );
4997  }
4998  knockback( traj, stun, dam_mult );
4999  break;
5000  }
5001  targ->setpos( traj[i] );
5002  }
5003  } else if( u.pos() == tp ) {
5004  if( stun > 0 ) {
5005  u.add_effect( effect_stunned, 1_turns * stun );
5006  add_msg( m_bad, n_gettext( "You were stunned for %d turn!",
5007  "You were stunned for %d turns!",
5008  stun ),
5009  stun );
5010  }
5011  for( size_t i = 1; i < traj.size(); i++ ) {
5012  if( m.impassable( traj[i] ) ) { // oops, we hit a wall!
5013  u.setpos( traj[i - 1] );
5014  force_remaining = traj.size() - i;
5015  if( stun != 0 ) {
5016  if( u.has_effect( effect_stunned ) ) {
5017  add_msg( m_bad, n_gettext( "You were stunned AGAIN for %d turn!",
5018  "You were stunned AGAIN for %d turns!",
5019  force_remaining ),
5020  force_remaining );
5021  } else {
5022  add_msg( m_bad, n_gettext( "You were stunned for %d turn!",
5023  "You were stunned for %d turns!",
5024  force_remaining ),
5025  force_remaining );
5026  }
5027  u.add_effect( effect_stunned, 1_turns * force_remaining );
5028  std::array<bodypart_id, 8> bps = {{
5029  bodypart_id( "head" ),
5030  bodypart_id( "arm_l" ), bodypart_id( "arm_r" ),
5031  bodypart_id( "hand_l" ), bodypart_id( "hand_r" ),
5032  bodypart_id( "torso" ),
5033  bodypart_id( "leg_l" ), bodypart_id( "leg_r" )
5034  }
5035  };
5036  for( const bodypart_id &bp : bps ) {
5037  if( one_in( 2 ) ) {
5038  u.deal_damage( nullptr, bp, damage_instance( damage_bash, force_remaining * dam_mult ) );
5039  }
5040  }
5041  u.check_dead_state();
5042  }
5043  m.bash( traj[i], 2 * dam_mult * force_remaining );
5044  break;
5045  } else if( creatures.creature_at( traj[i] ) ) {
5046  u.setpos( traj[i - 1] );
5047  force_remaining = traj.size() - i;
5048  if( stun != 0 ) {
5049  if( u.has_effect( effect_stunned ) ) {
5050  add_msg( m_bad, n_gettext( "You were stunned AGAIN for %d turn!",
5051  "You were stunned AGAIN for %d turns!",
5052  force_remaining ),
5053  force_remaining );
5054  } else {
5055  add_msg( m_bad, n_gettext( "You were stunned for %d turn!",
5056  "You were stunned for %d turns!",
5057  force_remaining ),
5058  force_remaining );
5059  }
5060  u.add_effect( effect_stunned, 1_turns * force_remaining );
5061  }
5062  traj.erase( traj.begin(), traj.begin() + i );
5063  if( creatures.creature_at<monster>( traj.front() ) ) {
5064  add_msg( _( "You collided with something and sent it flying!" ) );
5065  } else if( npc *const guy = creatures.creature_at<npc>( traj.front() ) ) {
5066  if( guy->male ) {
5067  add_msg( _( "You collided with someone and sent him flying!" ) );
5068  } else {
5069  add_msg( _( "You collided with someone and sent her flying!" ) );
5070  }
5071  }
5072  knockback( traj, stun, dam_mult );
5073  break;
5074  }
5075  if( m.has_flag( ter_furn_flag::TFLAG_LIQUID, u.pos() ) && force_remaining == 0 ) {
5076  avatar_action::swim( m, u, u.pos() );
5077  } else {
5078  u.setpos( traj[i] );
5079  }
5080  }
5081  }
5082 }
bool is_barefoot() const
Returns true if the player is not wearing anything that covers the soles of their feet,...
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d, const weakpoint_attack &attack=weakpoint_attack()) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8263
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.h:604
static const trait_id trait_LEG_TENT_BRACE("LEG_TENT_BRACE")
static const efftype_id effect_stunned("stunned")
mon_flag_id mon_flag_AQUATIC
Definition: mtype.cpp:48
void swim(map &m, avatar &you, const tripoint &p)
Handles swimming by the player.

References _, Creature::add_effect(), add_msg(), map::bash(), bp, Creature::check_dead_state(), creature_tracker::creature_at(), damage_bash, Character::deal_damage(), debugmsg, effect_stunned, get_creature_tracker, Creature::has_effect(), map::has_flag(), Character::has_trait(), map::impassable(), Character::is_barefoot(), knockback(), m, m_bad, mon_flag_AQUATIC, n_gettext, one_in(), Creature::pos(), Creature::posx(), Creature::posy(), Character::sees(), Creature::setpos(), avatar_action::swim(), TFLAG_LIQUID, trait_LEG_TENT_BRACE, u, tripoint::x, tripoint::y, and tripoint::z.

◆ light_level()

unsigned char game::light_level ( int  zlev) const

Returns coarse number-of-squares of visibility at the current light level.

Used by monster and NPC AI.

Definition at line 4452 of file game.cpp.

4453 {
4454  const float light = natural_light_level( zlev );
4455  return LIGHT_RANGE( light );
4456 }
float natural_light_level(int zlev) const
Definition: game.cpp:4396
constexpr int LIGHT_RANGE(float b)
Definition: lightmap.h:41

References light, LIGHT_RANGE(), and natural_light_level().

Referenced by calc_driving_offset(), and update_overmap_seen().

◆ list_active_saves()

std::vector< std::string > game::list_active_saves ( )

Returns a list of currently active character saves.

Definition at line 3517 of file game.cpp.

3518 {
3519  std::vector<std::string> saves;
3520  for( save_t &worldsave : world_generator->active_world->world_saves ) {
3521  saves.push_back( worldsave.decoded_name() );
3522  }
3523  return saves;
3524 }
std::string decoded_name() const

References save_t::decoded_name(), and world_generator.

◆ list_items()

game::vmenu_ret game::list_items ( const std::vector< map_item_stack > &  item_list)
private

Definition at line 8421 of file game.cpp.

8422 {
8423  std::vector<map_item_stack> ground_items = item_list;
8424  int iInfoHeight = 0;
8425  int iMaxRows = 0;
8426  int width = 0;
8427  int width_nob = 0; // width without borders
8428  int max_name_width = 0;
8429 
8430  const bool highlight_unread_items = get_option<bool>( "HIGHLIGHT_UNREAD_ITEMS" );
8431  const nc_color item_new_col = c_light_green;
8432  const nc_color item_maybe_new_col = c_light_gray;
8433  const std::string item_new_str = pgettext( "crafting gui", "NEW!" );
8434  const std::string item_maybe_new_str = pgettext( "crafting gui", "hides contents" );
8435  const int item_new_str_width = utf8_width( item_new_str );
8436  const int item_maybe_new_str_width = utf8_width( item_maybe_new_str );
8437 
8438  // Constants for content that is always displayed in w_items
8439  // on left: 1 space
8440  const int left_padding = 1;
8441  // on right: 2 digit distance 1 space 2 direction 1 space
8442  const int right_padding = 2 + 1 + 2 + 1;
8443  const int padding = left_padding + right_padding;
8444 
8445  //find max length of item name and resize window width
8446  for( const map_item_stack &cur_item : ground_items ) {
8447  max_name_width = std::max( max_name_width,
8448  utf8_width( remove_color_tags( cur_item.example->display_name() ) ) );
8449  }
8450  // + 6 as estimate for `iThisPage` I guess
8451  max_name_width = max_name_width + padding + 6 + ( highlight_unread_items ? std::max(
8452  item_new_str_width, item_maybe_new_str_width ) : 0 );
8453 
8454  tripoint active_pos;
8455  map_item_stack *activeItem = nullptr;
8456 
8457  catacurses::window w_items;
8458  catacurses::window w_items_border;
8459  catacurses::window w_item_info;
8460 
8461  ui_adaptor ui;
8462  ui.on_screen_resize( [&]( ui_adaptor & ui ) {
8463  iInfoHeight = std::min( 25, TERMY / 2 );
8464  iMaxRows = TERMY - iInfoHeight - 2;
8465 
8466  width = clamp( max_name_width, 55, TERMX / 3 );
8467  width_nob = width - 2;
8468 
8469  const int offsetX = TERMX - width;
8470 
8471  w_items = catacurses::newwin( TERMY - 2 - iInfoHeight,
8472  width_nob, point( offsetX + 1, 1 ) );
8473  w_items_border = catacurses::newwin( TERMY - iInfoHeight,
8474  width, point( offsetX, 0 ) );
8475  w_item_info = catacurses::newwin( iInfoHeight, width,
8476  point( offsetX, TERMY - iInfoHeight ) );
8477 
8478  if( activeItem ) {
8479  centerlistview( active_pos, width );
8480  }
8481 
8482  ui.position( point( offsetX, 0 ), point( width, TERMY ) );
8483  } );
8484  ui.mark_resize();
8485 
8486  // use previously selected sorting method
8487  bool sort_radius = uistate.list_item_sort != 2;
8488  bool addcategory = !sort_radius;
8489 
8490  // reload filter/priority settings on the first invocation, if they were active
8491  if( !uistate.list_item_init ) {
8494  }
8497  }
8500  }
8501  uistate.list_item_init = true;
8502  }
8503 
8504  //this stores only those items that match our filter
8505  std::vector<map_item_stack> filtered_items =
8506  !sFilter.empty() ? filter_item_stacks( ground_items, sFilter ) : ground_items;
8507  int highPEnd = list_filter_high_priority( filtered_items, list_item_upvote );
8508  int lowPStart = list_filter_low_priority( filtered_items, highPEnd, list_item_downvote );
8509  int iItemNum = ground_items.size();
8510 
8511  const tripoint stored_view_offset = u.view_offset;
8512 
8514 
8515  int iActive = 0; // Item index that we're looking at
8516  bool refilter = true;
8517  int page_num = 0;
8518  int iCatSortNum = 0;
8519  int iScrollPos = 0;
8520  std::map<int, std::string> mSortCategory;
8521 
8522  std::string action;
8523  input_context ctxt( "LIST_ITEMS" );
8524  ctxt.register_action( "UP", to_translation( "Move cursor up" ) );
8525  ctxt.register_action( "DOWN", to_translation( "Move cursor down" ) );
8526  ctxt.register_action( "LEFT", to_translation( "Previous item" ) );
8527  ctxt.register_action( "RIGHT", to_translation( "Next item" ) );
8528  ctxt.register_action( "PAGE_UP", to_translation( "Fast scroll up" ) );
8529  ctxt.register_action( "PAGE_DOWN", to_translation( "Fast scroll down" ) );
8530  ctxt.register_action( "SCROLL_ITEM_INFO_DOWN" );
8531  ctxt.register_action( "SCROLL_ITEM_INFO_UP" );
8532  ctxt.register_action( "zoom_in" );
8533  ctxt.register_action( "zoom_out" );
8534  ctxt.register_action( "NEXT_TAB" );
8535  ctxt.register_action( "PREV_TAB" );
8536  ctxt.register_action( "HELP_KEYBINDINGS" );
8537  ctxt.register_action( "QUIT" );
8538  ctxt.register_action( "FILTER" );
8539  ctxt.register_action( "RESET_FILTER" );
8540  ctxt.register_action( "EXAMINE" );
8541  ctxt.register_action( "COMPARE" );
8542  ctxt.register_action( "PRIORITY_INCREASE" );
8543  ctxt.register_action( "PRIORITY_DECREASE" );
8544  ctxt.register_action( "SORT" );
8545  ctxt.register_action( "TRAVEL_TO" );
8546 
8547  ui.on_redraw( [&]( ui_adaptor & ui ) {
8548  reset_item_list_state( w_items_border, iInfoHeight, sort_radius );
8549 
8550  int iStartPos = 0;
8551  if( ground_items.empty() ) {
8552  wnoutrefresh( w_items_border );
8553  mvwprintz( w_items, point( 2, 10 ), c_white, _( "You don't see any items around you!" ) );
8554  } else {
8555  werase( w_items );
8556  calcStartPos( iStartPos, iActive, iMaxRows, iItemNum );
8557  int iNum = 0;
8558  // ITEM LIST
8559  int index = 0;
8560  int iCatSortOffset = 0;
8561 
8562  for( int i = 0; i < iStartPos; i++ ) {
8563  if( !mSortCategory[i].empty() ) {
8564  iNum++;
8565  }
8566  }
8567  for( auto iter = filtered_items.begin(); iter != filtered_items.end(); ++index, iNum++ ) {
8568  if( iNum < iStartPos || iNum >= iStartPos + std::min( iMaxRows, iItemNum ) ) {
8569  ++iter;
8570  continue;
8571  }
8572  int iThisPage = 0;
8573  if( !mSortCategory[iNum].empty() ) {
8574  iCatSortOffset++;
8575  mvwprintz( w_items, point( 1, iNum - iStartPos ), c_magenta, mSortCategory[iNum] );
8576  continue;
8577  }
8578  if( iNum == iActive ) {
8579  iThisPage = page_num;
8580  }
8581  std::string sText;
8582  if( iter->vIG.size() > 1 ) {
8583  sText += string_format( "[%d/%d] (%d) ", iThisPage + 1, iter->vIG.size(), iter->totalcount );
8584  }
8585  sText += iter->example->tname();
8586  if( iter->vIG[iThisPage].count > 1 ) {
8587  sText += string_format( "[%d]", iter->vIG[iThisPage].count );
8588  }
8589 
8590  nc_color col = c_light_gray;
8591  if( iNum == iActive ) {
8592  col = hilite( c_white );
8593  } else if( highPEnd > 0 && index < highPEnd + iCatSortOffset ) { // priority high
8594  col = c_yellow;
8595  } else if( index >= lowPStart + iCatSortOffset ) { // priority low
8596  col = c_red;
8597  } else { // priority medium
8598  col = iter->example->color_in_inventory();
8599  }
8600  bool print_new = highlight_unread_items;
8601  const std::string *new_str = nullptr;
8602  // 1 make space between item description and right padding (distance)
8603  int new_width = 1;
8604  const nc_color *new_col = nullptr;
8605  if( print_new ) {
8606  switch( check_items_newness( iter->example ) ) {
8607  case content_newness::NEW:
8608  new_str = &item_new_str;
8609  // +1 make space between item description and "new"
8610  new_width += item_new_str_width + 1;
8611  new_col = &item_new_col;
8612  break;
8614  new_str = &item_maybe_new_str;
8615  new_width += item_maybe_new_str_width + 1;
8616  new_col = &item_maybe_new_col;
8617  break;
8618  case content_newness::SEEN:
8619  print_new = false;
8620  break;
8621  }
8622  }
8623  trim_and_print( w_items, point( 1, iNum - iStartPos ), width_nob - padding - new_width, col,
8624  sText );
8625  const point p( iter->vIG[iThisPage].pos.xy() );
8626  if( print_new ) {
8627  // +1 move space between item description and "new"
8628  mvwprintz( w_items, point( width_nob - right_padding - new_width + 1, iNum - iStartPos ), *new_col,
8629  *new_str );
8630  }
8631  mvwprintz( w_items, point( width_nob - right_padding, iNum - iStartPos ),
8632  iNum == iActive ? c_light_green : c_light_gray,
8633  "%2d %s", rl_dist( point_zero, p ),
8635  ++iter;
8636  }
8637  // ITEM DESCRIPTION
8638  iNum = 0;
8639  for( int i = 0; i < iActive; i++ ) {
8640  if( !mSortCategory[i].empty() ) {
8641  iNum++;
8642  }
8643  }
8644  const int current_i = iItemNum > 0 ? iActive - iNum + 1 : 0;
8645  const int numd = current_i > 999 ? 4 :
8646  current_i > 99 ? 3 :
8647  current_i > 9 ? 2 : 1;
8648  mvwprintz( w_items_border, point( width / 2 - numd - 2, 0 ), c_light_green, " %*d", numd,
8649  current_i );
8650  wprintz( w_items_border, c_white, " / %*d ", numd, iItemNum - iCatSortNum );
8651  werase( w_item_info );
8652 
8653  if( iItemNum > 0 && activeItem ) {
8654  std::vector<iteminfo> vThisItem;
8655  std::vector<iteminfo> vDummy;
8656  activeItem->vIG[page_num].it->info( true, vThisItem );
8657 
8658  item_info_data dummy( "", "", vThisItem, vDummy, iScrollPos );
8659  dummy.without_getch = true;
8660  dummy.without_border = true;
8661 
8662  draw_item_info( w_item_info, dummy );
8663  }
8664  draw_scrollbar( w_items_border, iActive, iMaxRows, iItemNum, point_south );
8665  wnoutrefresh( w_items_border );
8666  }
8667 
8668  const bool bDrawLeft = ground_items.empty() || filtered_items.empty() || !activeItem;
8669  draw_custom_border( w_item_info, bDrawLeft, 1, 1, 1, LINE_XXXO, LINE_XOXX, 1, 1 );
8670 
8671  if( iItemNum > 0 && activeItem ) {
8672  // print info window title: < item name >
8673  mvwprintw( w_item_info, point( 2, 0 ), "< " );
8674  trim_and_print( w_item_info, point( 4, 0 ), width_nob - padding,
8675  activeItem->vIG[page_num].it->color_in_inventory(),
8676  activeItem->vIG[page_num].it->display_name() );
8677  wprintw( w_item_info, " >" );
8678  // move the cursor to the selected item (for screen readers)
8679  ui.set_cursor( w_items, point( 1, iActive - iStartPos ) );
8680  }
8681 
8682  wnoutrefresh( w_items );
8683  wnoutrefresh( w_item_info );
8684  } );
8685 
8686  std::optional<tripoint> trail_start;
8687  std::optional<tripoint> trail_end;
8688  bool trail_end_x = false;
8689  shared_ptr_fast<draw_callback_t> trail_cb = create_trail_callback( trail_start, trail_end,
8690  trail_end_x );
8691  add_draw_callback( trail_cb );
8692 
8693  do {
8694  bool recalc_unread = false;
8695  if( action == "COMPARE" && activeItem ) {
8696  game_menus::inv::compare( u, active_pos );
8697  recalc_unread = highlight_unread_items;
8698  } else if( action == "FILTER" ) {
8699  ui.invalidate_ui();
8701  .title( _( "Filter:" ) )
8702  .width( 55 )
8705  .desc_color( c_white )
8706  .identifier( "item_filter" )
8707  .max_length( 256 )
8708  .edit( sFilter );
8709  refilter = true;
8710  addcategory = !sort_radius;
8712  } else if( action == "RESET_FILTER" ) {
8713  sFilter.clear();
8714  filtered_items = ground_items;
8715  refilter = true;
8717  addcategory = !sort_radius;
8718  } else if( action == "EXAMINE" && !filtered_items.empty() && activeItem ) {
8719  std::vector<iteminfo> vThisItem;
8720  std::vector<iteminfo> vDummy;
8721  activeItem->vIG[page_num].it->info( true, vThisItem );
8722 
8723  item_info_data info_data( activeItem->vIG[page_num].it->tname(),
8724  activeItem->vIG[page_num].it->type_name(), vThisItem,
8725  vDummy );
8726  info_data.handle_scrolling = true;
8727 
8729  return catacurses::newwin( TERMY, width - 5, point_zero );
8730  }, info_data );
8731  recalc_unread = highlight_unread_items;
8732  } else if( action == "PRIORITY_INCREASE" ) {
8733  ui.invalidate_ui();
8735  .title( _( "High Priority:" ) )
8736  .width( 55 )
8740  .desc_color( c_white )
8741  .identifier( "list_item_priority" )
8742  .max_length( 256 )
8743  .query_string();
8744  refilter = true;
8745  addcategory = !sort_radius;
8747  } else if( action == "PRIORITY_DECREASE" ) {
8748  ui.invalidate_ui();
8750  .title( _( "Low Priority:" ) )
8751  .width( 55 )
8755  .desc_color( c_white )
8756  .identifier( "list_item_downvote" )
8757  .max_length( 256 )
8758  .query_string();
8759  refilter = true;
8760  addcategory = !sort_radius;
8762  } else if( action == "SORT" ) {
8763  if( sort_radius ) {
8764  sort_radius = false;
8765  addcategory = true;
8766  uistate.list_item_sort = 2; // list is sorted by category
8767  } else {
8768  sort_radius = true;
8769  uistate.list_item_sort = 1; // list is sorted by distance
8770  }
8771  highPEnd = -1;
8772  lowPStart = -1;
8773  iCatSortNum = 0;
8774 
8775  mSortCategory.clear();
8776  refilter = true;
8777  } else if( action == "TRAVEL_TO" && activeItem ) {
8778  // try finding route to the tile, or one tile away from it
8779  const std::optional<std::vector<tripoint_bub_ms>> try_route =
8780  safe_route_to( u, u.pos_bub() + active_pos, 1, []( const std::string & msg ) {
8781  popup( msg );
8782  } );
8783  recalc_unread = highlight_unread_items;
8784  if( try_route.has_value() ) {
8785  u.set_destination( *try_route );
8786  break;
8787  }
8788  }
8789  if( uistate.list_item_sort == 1 ) {
8790  ground_items = item_list;
8791  } else if( uistate.list_item_sort == 2 ) {
8792  std::sort( ground_items.begin(), ground_items.end(), map_item_stack::map_item_stack_sort );
8793  }
8794 
8795  if( refilter ) {
8796  refilter = false;
8797  filtered_items = filter_item_stacks( ground_items, sFilter );
8798  highPEnd = list_filter_high_priority( filtered_items, list_item_upvote );
8799  lowPStart = list_filter_low_priority( filtered_items, highPEnd, list_item_downvote );
8800  iActive = 0;
8801  page_num = 0;
8802  iItemNum = filtered_items.size();
8803  }
8804 
8805  if( addcategory ) {
8806  addcategory = false;
8807  iCatSortNum = 0;
8808  mSortCategory.clear();
8809  if( highPEnd > 0 ) {
8810  mSortCategory[0] = _( "HIGH PRIORITY" );
8811  iCatSortNum++;
8812  }
8813  std::string last_cat_name;
8814  for( int i = std::max( 0, highPEnd );
8815  i < std::min( lowPStart, static_cast<int>( filtered_items.size() ) ); i++ ) {
8816  const std::string &cat_name =
8817  filtered_items[i].example->get_category_of_contents().name_header();
8818  if( cat_name != last_cat_name ) {
8819  mSortCategory[i + iCatSortNum++] = cat_name;
8820  last_cat_name = cat_name;
8821  }
8822  }
8823  if( lowPStart < static_cast<int>( filtered_items.size() ) ) {
8824  mSortCategory[lowPStart + iCatSortNum++] = _( "LOW PRIORITY" );
8825  }
8826  if( !mSortCategory[0].empty() ) {
8827  iActive++;
8828  }
8829  iItemNum = static_cast<int>( filtered_items.size() ) + iCatSortNum;
8830  }
8831 
8832  const int item_info_scroll_lines = catacurses::getmaxy( w_item_info ) - 4;
8833  const int scroll_rate = iItemNum > 20 ? 10 : 3;
8834 
8835  if( action == "UP" ) {
8836  do {
8837  iActive--;
8838  } while( !mSortCategory[iActive].empty() );
8839  iScrollPos = 0;
8840  page_num = 0;
8841  if( iActive < 0 ) {
8842  iActive = iItemNum - 1;
8843  }
8844  recalc_unread = highlight_unread_items;
8845  } else if( action == "DOWN" ) {
8846  do {
8847  iActive++;
8848  } while( !mSortCategory[iActive].empty() );
8849  iScrollPos = 0;
8850  page_num = 0;
8851  if( iActive >= iItemNum ) {
8852  iActive = mSortCategory[0].empty() ? 0 : 1;
8853  }
8854  recalc_unread = highlight_unread_items;
8855  } else if( action == "PAGE_DOWN" ) {
8856  iScrollPos = 0;
8857  page_num = 0;
8858  if( iActive == iItemNum - 1 ) {
8859  iActive = mSortCategory[0].empty() ? 0 : 1;
8860  } else if( iActive + scroll_rate >= iItemNum ) {
8861  iActive = iItemNum - 1;
8862  } else {
8863  iActive += +scroll_rate - 1;
8864  do {
8865  iActive++;
8866  } while( !mSortCategory[iActive].empty() );
8867  }
8868  } else if( action == "PAGE_UP" ) {
8869  iScrollPos = 0;
8870  page_num = 0;
8871  if( mSortCategory[0].empty() ? iActive == 0 : iActive == 1 ) {
8872  iActive = iItemNum - 1;
8873  } else if( iActive <= scroll_rate ) {
8874  iActive = mSortCategory[0].empty() ? 0 : 1;
8875  } else {
8876  iActive += -scroll_rate + 1;
8877  do {
8878  iActive--;
8879  } while( !mSortCategory[iActive].empty() );
8880  }
8881  } else if( action == "RIGHT" ) {
8882  if( !filtered_items.empty() && activeItem ) {
8883  if( ++page_num >= static_cast<int>( activeItem->vIG.size() ) ) {
8884  page_num = activeItem->vIG.size() - 1;
8885  }
8886  }
8887  recalc_unread = highlight_unread_items;
8888  } else if( action == "LEFT" ) {
8889  page_num = std::max( 0, page_num - 1 );
8890  recalc_unread = highlight_unread_items;
8891  } else if( action == "SCROLL_ITEM_INFO_UP" ) {
8892  iScrollPos -= item_info_scroll_lines;
8893  recalc_unread = highlight_unread_items;
8894  } else if( action == "SCROLL_ITEM_INFO_DOWN" ) {
8895  iScrollPos += item_info_scroll_lines;
8896  recalc_unread = highlight_unread_items;
8897  } else if( action == "zoom_in" ) {
8898  zoom_in();
8900  } else if( action == "zoom_out" ) {
8901  zoom_out();
8903  } else if( action == "NEXT_TAB" || action == "PREV_TAB" ) {
8904  u.view_offset = stored_view_offset;
8906  }
8907 
8908  active_pos = tripoint_zero;
8909  activeItem = nullptr;
8910 
8911  if( mSortCategory[iActive].empty() ) {
8912  auto iter = filtered_items.begin();
8913  for( int iNum = 0; iter != filtered_items.end() && iNum < iActive; iNum++ ) {
8914  if( mSortCategory[iNum].empty() ) {
8915  ++iter;
8916  }
8917  }
8918  if( iter != filtered_items.end() ) {
8919  active_pos = iter->vIG[page_num].pos;
8920  activeItem = &( *iter );
8921  }
8922  }
8923 
8924  if( activeItem ) {
8925  centerlistview( active_pos, width );
8926  trail_start = u.pos();
8927  trail_end = u.pos() + active_pos;
8928  // Actually accessed from the terrain overlay callback `trail_cb` in the
8929  // call to `ui_manager::redraw`.
8930  //NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
8931  trail_end_x = true;
8932  if( recalc_unread ) {
8933  mark_items_read_rec( activeItem->example );
8934  }
8935  } else {
8936  u.view_offset = stored_view_offset;
8937  trail_start = trail_end = std::nullopt;
8938  }
8940 
8942 
8943  action = ctxt.handle_input();
8944  } while( action != "QUIT" );
8945 
8946  u.view_offset = stored_view_offset;
8947  return game::vmenu_ret::QUIT;
8948 }
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:221
std::string list_item_upvote
Definition: game.h:1161
std::string list_item_downvote
Definition: game.h:1162
std::string sFilter
Definition: game.h:1160
void reset_item_list_state(const catacurses::window &window, int height, bool bRadiusSort)
Definition: game.cpp:8278
std::optional< std::vector< tripoint_bub_ms > > safe_route_to(Character &who, const tripoint_bub_ms &target, int threshold, const std::function< void(const std::string &msg)> &report) const
attempt to find a safe route (avoids tiles dangerous to 'who').
Definition: game.cpp:7588
static bool map_item_stack_sort(const map_item_stack &lhs, const map_item_stack &rhs)
std::vector< item_group > vIG
const item * example
string_input_popup & identifier(const std::string &value)
An identifier to be used to store / get the input history.
string_input_popup & text(const std::string &value)
Set / get the text that can be modified by the user.
void edit(std::string &value)
Edit values in place.
string_input_popup & desc_color(const nc_color &color)
Set / get the foreground color of the description.
string_input_popup & description(const std::string &value)
Additional help text, shown below the input box.
string_input_popup & title(const std::string &value)
The title: short string before the actual input field.
string_input_popup & width(int value)
Width (in console cells) of the input field itself.
std::string list_item_priority
Definition: uistate.h:169
int list_item_sort
Definition: uistate.h:162
bool list_item_downvote_active
Definition: uistate.h:172
bool list_item_init
Definition: uistate.h:174
bool list_item_filter_active
Definition: uistate.h:171
std::string list_item_filter
Definition: uistate.h:167
bool list_item_priority_active
Definition: uistate.h:173
std::string list_item_downvote
Definition: uistate.h:168
nc_color hilite(const nc_color &c)
Definition: color.cpp:546
static content_newness check_items_newness(const item *itm)
return content_newness based on if item is known and nested items are known
Definition: game.cpp:8404
static shared_ptr_fast< game::draw_callback_t > create_trail_callback(const std::optional< tripoint > &trail_start, const std::optional< tripoint > &trail_end, const bool &trail_end_x)
Definition: game.cpp:3898
static std::string list_items_filter_history_help()
Definition: game.cpp:8398
static void mark_items_read_rec(const item *itm)
add item and all visible nested items inside to known items
Definition: game.cpp:8413
static void centerlistview(const tripoint &active_item_position, int ui_width)
Definition: game.cpp:8101
std::string direction_name_short(const direction dir)
Definition: line.cpp:617
int list_filter_high_priority(std::vector< map_item_stack > &stack, const std::string &priorities)
std::vector< map_item_stack > filter_item_stacks(const std::vector< map_item_stack > &stack, const std::string &filter)
int list_filter_low_priority(std::vector< map_item_stack > &stack, const int start, const std::string &priorities)
void mvwprintw(const window &win, const point &p, const std::string &text)
void wprintw(const window &win, const std::string &text)
void calcStartPos(int &iStartPos, const int iCurrentLine, const int iContentHeight, const int iNumEntries)
Definition: output.cpp:2278
void draw_scrollbar(const catacurses::window &window, const int iCurrentLine, const int iContentHeight, const int iNumLines, const point &offset, nc_color bar_color, const bool bDoNotScrollToEnd)
Draw a scrollbar (Legacy function, use class scrollbar instead!)
Definition: output.cpp:1704
std::string item_filter_rule_string(const item_filter_type type)
Get the tips printed by draw_item_filter_rules as a string.
Definition: output.cpp:1058
void draw_custom_border(const catacurses::window &w, const catacurses::chtype ls, const catacurses::chtype rs, const catacurses::chtype ts, const catacurses::chtype bs, const catacurses::chtype tl, const catacurses::chtype tr, const catacurses::chtype bl, const catacurses::chtype br, const nc_color &FG, const point &pos, int height, int width)
Definition: output.cpp:637
std::string remove_color_tags(const std::string_view s)
Removes the color tags from the input string.
Definition: output.cpp:200
void trim_and_print(const catacurses::window &w, const point &begin, const int width, const nc_color &base_color, const std::string &text, const report_color_error color_error)
Prints a single line of text.
Definition: output.cpp:268
#define LINE_XOXX
Definition: output.h:54
#define LINE_XXXO
Definition: output.h:52

References _, action, add_draw_callback(), c_light_gray, c_light_green, c_magenta, c_red, c_white, c_yellow, calcStartPos(), centerlistview(), CHANGE_TAB, check_items_newness(), clamp(), game_menus::inv::compare(), create_trail_callback(), string_input_popup::desc_color(), string_input_popup::description(), direction_from(), direction_name_short(), draw_custom_border(), draw_item_info(), draw_scrollbar(), string_input_popup::edit(), map_item_stack::example, FILTER, filter_item_stacks(), catacurses::getmaxy(), input_context::handle_input(), item_info_data::handle_scrolling, HIGH_PRIORITY, hilite(), string_input_popup::identifier(), invalidate_main_ui_adaptor(), item_filter_rule_string(), LINE_XOXX, LINE_XXXO, list_filter_high_priority(), list_filter_low_priority(), list_item_downvote, uistatedata::list_item_downvote, uistatedata::list_item_downvote_active, uistatedata::list_item_filter, uistatedata::list_item_filter_active, uistatedata::list_item_init, uistatedata::list_item_priority, uistatedata::list_item_priority_active, uistatedata::list_item_sort, list_item_upvote, list_items_filter_history_help(), LOW_PRIORITY, map_item_stack::map_item_stack_sort(), mark_items_read_rec(), mark_main_ui_adaptor_resize(), max(), string_input_popup::max_length(), MIGHT_BE_HIDDEN, min(), catacurses::mvwprintw(), mvwprintz(), NEW, catacurses::newwin(), pgettext, point, point_south, point_zero, Creature::pos(), Creature::pos_bub(), string_input_popup::query_string(), QUIT, ui_manager::redraw(), input_context::register_action(), remove_color_tags(), reset_item_list_state(), rl_dist(), safe_route_to(), SEEN, Character::set_destination(), sFilter, string_format(), TERMX, TERMY, string_input_popup::text(), string_input_popup::title(), to_translation(), trim_and_print(), tripoint_zero, u, uistate, utf8_width(), Character::view_offset, map_item_stack::vIG, catacurses::werase(), string_input_popup::width(), item_info_data::without_border, item_info_data::without_getch, catacurses::wnoutrefresh(), catacurses::wprintw(), wprintz(), zoom_in(), and zoom_out().

◆ list_items_monsters()

void game::list_items_monsters ( )
private

Definition at line 8347 of file game.cpp.

8348 {
8349  // Search whole reality bubble because each function internally verifies
8350  // the visibility of the items / monsters in question.
8351  std::vector<Creature *> mons = u.get_visible_creatures( 60 );
8352  const std::vector<map_item_stack> items = find_nearby_items( 60 );
8353 
8354  if( mons.empty() && items.empty() ) {
8355  add_msg( m_info, _( "You don't see any items or monsters around you!" ) );
8356  return;
8357  }
8358 
8359  std::sort( mons.begin(), mons.end(), [&]( const Creature * lhs, const Creature * rhs ) {
8360  if( !u.has_trait( trait_INATTENTIVE ) ) {
8361  const Creature::Attitude att_lhs = lhs->attitude_to( u );
8362  const Creature::Attitude att_rhs = rhs->attitude_to( u );
8363 
8364  return att_lhs < att_rhs || ( att_lhs == att_rhs
8365  && rl_dist( u.pos(), lhs->pos() ) < rl_dist( u.pos(), rhs->pos() ) );
8366  } else { // Sort just by ditance if player has inattentive trait
8367  return ( rl_dist( u.pos(), lhs->pos() ) < rl_dist( u.pos(), rhs->pos() ) );
8368  }
8369 
8370  } );
8371 
8372  // If the current list is empty, switch to the non-empty list
8373  if( uistate.vmenu_show_items ) {
8374  if( items.empty() ) {
8375  uistate.vmenu_show_items = false;
8376  }
8377  } else if( mons.empty() ) {
8378  uistate.vmenu_show_items = true;
8379  }
8380 
8383  while( true ) {
8384  ret = uistate.vmenu_show_items ? list_items( items ) : list_monsters( mons );
8385  if( ret == game::vmenu_ret::CHANGE_TAB ) {
8387  } else {
8388  break;
8389  }
8390  }
8391 
8392  if( ret == game::vmenu_ret::FIRE ) {
8394  }
8396 }
game::vmenu_ret list_monsters(const std::vector< Creature * > &monster_list)
Definition: game.cpp:8950
game::vmenu_ret list_items(const std::vector< map_item_stack > &item_list)
Definition: game.cpp:8421
vmenu_ret
Definition: game.h:872
std::vector< map_item_stack > find_nearby_items(int iRadius)
Definition: game.cpp:8035
void temp_exit_fullscreen()
Definition: game.cpp:742
void reenter_fullscreen()
Definition: game.cpp:752
bool vmenu_show_items
Definition: uistate.h:170

References _, add_msg(), find_nearby_items(), Character::get_visible_creatures(), m_info, and u.

Referenced by do_regular_action(), and look_around().

◆ list_missions()

void game::list_missions ( )

Definition at line 312 of file mission_ui.cpp.

313 {
314  mission_ui new_instance;
315  new_instance.draw_mission_ui();
316 }
void draw_mission_ui()
Definition: mission_ui.cpp:82

References mission_ui::draw_mission_ui().

Referenced by do_regular_action().

◆ list_monsters()

game::vmenu_ret game::list_monsters ( const std::vector< Creature * > &  monster_list)
private

Definition at line 8950 of file game.cpp.

8951 {
8952  const int iInfoHeight = 15;
8953  const int width = 55;
8954  int offsetX = 0;
8955  int iMaxRows = 0;
8956 
8957  catacurses::window w_monsters;
8958  catacurses::window w_monsters_border;
8959  catacurses::window w_monster_info;
8960  catacurses::window w_monster_info_border;
8961 
8962  Creature *cCurMon = nullptr;
8963  tripoint iActivePos;
8964 
8965  bool hide_ui = false;
8966 
8967  ui_adaptor ui;
8968  ui.on_screen_resize( [&]( ui_adaptor & ui ) {
8969  if( hide_ui ) {
8970  ui.position( point_zero, point_zero );
8971  } else {
8972  offsetX = TERMX - width;
8973  iMaxRows = TERMY - iInfoHeight - 1;
8974 
8975  w_monsters = catacurses::newwin( iMaxRows, width - 2, point( offsetX + 1,
8976  1 ) );
8977  w_monsters_border = catacurses::newwin( iMaxRows + 1, width, point( offsetX,
8978  0 ) );
8979  w_monster_info = catacurses::newwin( iInfoHeight - 2, width - 2,
8980  point( offsetX + 1, TERMY - iInfoHeight + 1 ) );
8981  w_monster_info_border = catacurses::newwin( iInfoHeight, width, point( offsetX,
8982  TERMY - iInfoHeight ) );
8983 
8984  if( cCurMon ) {
8985  centerlistview( iActivePos, width );
8986  }
8987 
8988  ui.position( point( offsetX, 0 ), point( width, TERMY ) );
8989  }
8990  } );
8991  ui.mark_resize();
8992 
8993  int max_gun_range = 0;
8994  if( u.get_wielded_item() ) {
8995  max_gun_range = u.get_wielded_item()->gun_range( &u );
8996  }
8997 
8998  const tripoint stored_view_offset = u.view_offset;
9000 
9001  int iActive = 0; // monster index that we're looking at
9002 
9003  std::string action;
9004  input_context ctxt( "LIST_MONSTERS" );
9005  ctxt.register_navigate_ui_list();
9006  ctxt.register_action( "NEXT_TAB" );
9007  ctxt.register_action( "PREV_TAB" );
9008  ctxt.register_action( "zoom_in" );
9009  ctxt.register_action( "zoom_out" );
9010  ctxt.register_action( "SAFEMODE_BLACKLIST_ADD" );
9011  ctxt.register_action( "SAFEMODE_BLACKLIST_REMOVE" );
9012  ctxt.register_action( "QUIT" );
9013  if( bVMonsterLookFire ) {
9014  ctxt.register_action( "look" );
9015  ctxt.register_action( "fire" );
9016  }
9017  ctxt.register_action( "HELP_KEYBINDINGS" );
9018 
9019  // first integer is the row the attitude category string is printed in the menu
9020  std::map<int, Creature::Attitude> mSortCategory;
9021  const bool player_knows = !u.has_trait( trait_INATTENTIVE );
9022  if( player_knows ) {
9023  for( int i = 0, last_attitude = -1; i < static_cast<int>( monster_list.size() ); i++ ) {
9024  const Creature::Attitude attitude = monster_list[i]->attitude_to( u );
9025  if( static_cast<int>( attitude ) != last_attitude ) {
9026  mSortCategory[i + mSortCategory.size()] = attitude;
9027  last_attitude = static_cast<int>( attitude );
9028  }
9029  }
9030  }
9031 
9032  ui.on_redraw( [&]( const ui_adaptor & ) {
9033  if( !hide_ui ) {
9034  draw_custom_border( w_monsters_border, 1, 1, 1, 1, 1, 1, LINE_XOXO, LINE_XOXO );
9035  draw_custom_border( w_monster_info_border, 1, 1, 1, 1, LINE_XXXO, LINE_XOXX, 1, 1 );
9036 
9037  mvwprintz( w_monsters_border, point( 2, 0 ), c_light_green, "<Tab> " );
9038  wprintz( w_monsters_border, c_white, _( "Monsters" ) );
9039 
9040  if( monster_list.empty() ) {
9041  werase( w_monsters );
9042  mvwprintz( w_monsters, point( 2, iMaxRows / 3 ), c_white,
9043  _( "You don't see any monsters around you!" ) );
9044  } else {
9045  werase( w_monsters );
9046 
9047  const int iNumMonster = monster_list.size();
9048  const int iMenuSize = monster_list.size() + mSortCategory.size();
9049 
9050  const int numw = iNumMonster > 999 ? 4 :
9051  iNumMonster > 99 ? 3 :
9052  iNumMonster > 9 ? 2 : 1;
9053 
9054  // given the currently selected monster iActive. get the selected row
9055  int iSelPos = iActive;
9056  for( auto &ia : mSortCategory ) {
9057  int index = ia.first;
9058  if( index <= iSelPos ) {
9059  ++iSelPos;
9060  } else {
9061  break;
9062  }
9063  }
9064  int iStartPos = 0;
9065  // use selected row get the start row
9066  calcStartPos( iStartPos, iSelPos, iMaxRows - 1, iMenuSize );
9067 
9068  // get first visible monster and category
9069  int iCurMon = iStartPos;
9070  auto CatSortIter = mSortCategory.cbegin();
9071  while( CatSortIter != mSortCategory.cend() && CatSortIter->first < iStartPos ) {
9072  ++CatSortIter;
9073  --iCurMon;
9074  }
9075 
9076  std::string monNameSelected;
9077  std::string sSafemode;
9078  const int endY = std::min<int>( iMaxRows - 1, iMenuSize );
9079  for( int y = 0; y < endY; ++y ) {
9080 
9081  if( player_knows && CatSortIter != mSortCategory.cend() ) {
9082  const int iCurPos = iStartPos + y;
9083  const int iCatPos = CatSortIter->first;
9084  if( iCurPos == iCatPos ) {
9085  const std::string cat_name = Creature::get_attitude_ui_data(
9086  CatSortIter->second ).first.translated();
9087  mvwprintz( w_monsters, point( 1, y ), c_magenta, cat_name );
9088  ++CatSortIter;
9089  continue;
9090  }
9091  }
9092 
9093  // select current monster
9094  Creature *critter = monster_list[iCurMon];
9095  const bool selected = iCurMon == iActive;
9096  ++iCurMon;
9097  if( critter->sees( u ) && player_knows ) {
9098  mvwprintz( w_monsters, point( 0, y ), c_yellow, "!" );
9099  }
9100  bool is_npc = false;
9101  const monster *m = dynamic_cast<monster *>( critter );
9102  const npc *p = dynamic_cast<npc *>( critter );
9103  nc_color name_color = critter->basic_symbol_color();
9104 
9105  if( selected ) {
9106  name_color = hilite( name_color );
9107  }
9108 
9109  if( m != nullptr ) {
9110  trim_and_print( w_monsters, point( 1, y ), width - 32, name_color, m->name() );
9111  } else {
9112  trim_and_print( w_monsters, point( 1, y ), width - 32, name_color, critter->disp_name() );
9113  is_npc = true;
9114  }
9115 
9116  if( selected && !get_safemode().empty() ) {
9117  monNameSelected = is_npc ? get_safemode().npc_type_name() : m->name();
9118 
9119  if( get_safemode().has_rule( monNameSelected, Creature::Attitude::ANY ) ) {
9120  sSafemode = _( "<R>emove from safe mode blacklist" );
9121  } else {
9122  sSafemode = _( "<A>dd to safe mode blacklist" );
9123  }
9124  }
9125 
9127  std::string sText;
9128 
9129  if( m != nullptr ) {
9130  m->get_HP_Bar( color, sText );
9131  } else {
9132  std::tie( sText, color ) =
9133  ::get_hp_bar( critter->get_hp(), critter->get_hp_max(), false );
9134  }
9135  mvwprintz( w_monsters, point( width - 31, y ), color, sText );
9136  const int bar_max_width = 5;
9137  const int bar_width = utf8_width( sText );
9138  for( int i = 0; i < bar_max_width - bar_width; ++i ) {
9139  mvwprintz( w_monsters, point( width - 27 - i, y ), c_white, "." );
9140  }
9141 
9142  if( m != nullptr ) {
9143  const auto att = m->get_attitude();
9144  sText = att.first;
9145  color = att.second;
9146  } else if( p != nullptr ) {
9147  sText = npc_attitude_name( p->get_attitude() );
9148  color = p->symbol_color();
9149  }
9150  if( !player_knows ) {
9151  sText = _( "Unknown" );
9152  color = c_yellow;
9153  }
9154  mvwprintz( w_monsters, point( width - 19, y ), color, sText );
9155 
9156  const int mon_dist = rl_dist( u.pos(), critter->pos() );
9157  const int numd = mon_dist > 999 ? 4 :
9158  mon_dist > 99 ? 3 :
9159  mon_dist > 9 ? 2 : 1;
9160 
9161  trim_and_print( w_monsters, point( width - ( 5 + numd ), y ), 6 + numd,
9162  selected ? c_light_green : c_light_gray,
9163  "%*d %s",
9164  numd, mon_dist,
9165  direction_name_short( direction_from( u.pos(), critter->pos() ) ) );
9166  }
9167 
9168  mvwprintz( w_monsters_border, point( ( width / 2 ) - numw - 2, 0 ), c_light_green, " %*d", numw,
9169  iActive + 1 );
9170  wprintz( w_monsters_border, c_white, " / %*d ", numw, static_cast<int>( monster_list.size() ) );
9171 
9172  werase( w_monster_info );
9173  if( cCurMon ) {
9174  cCurMon->print_info( w_monster_info, 1, iInfoHeight - 3, 1 );
9175  }
9176 
9177  draw_custom_border( w_monster_info_border, 1, 1, 1, 1, LINE_XXXO, LINE_XOXX, 1, 1 );
9178 
9179  if( bVMonsterLookFire ) {
9180  mvwprintw( w_monster_info_border, point_east, "< " );
9181  wprintz( w_monster_info_border, c_light_green, ctxt.press_x( "look" ) );
9182  wprintz( w_monster_info_border, c_light_gray, " %s", _( "to look around" ) );
9183 
9184  if( cCurMon && rl_dist( u.pos(), cCurMon->pos() ) <= max_gun_range ) {
9185  std::string press_to_fire_text = string_format( _( "%s %s" ),
9186  ctxt.press_x( "fire" ),
9187  string_format( _( "<color_light_gray>to shoot</color>" ) ) );
9188  right_print( w_monster_info_border, 0, 3, c_light_green, press_to_fire_text );
9189  }
9190  wprintw( w_monster_info_border, " >" );
9191  }
9192 
9193  if( !get_safemode().empty() ) {
9194  if( get_safemode().has_rule( monNameSelected, Creature::Attitude::ANY ) ) {
9195  sSafemode = _( "<R>emove from safe mode blacklist" );
9196  } else {
9197  sSafemode = _( "<A>dd to safe mode blacklist" );
9198  }
9199 
9200  shortcut_print( w_monsters, point( 2, getmaxy( w_monsters ) - 1 ),
9201  c_white, c_light_green, sSafemode );
9202  }
9203 
9204  draw_scrollbar( w_monsters_border, iActive, iMaxRows, static_cast<int>( monster_list.size() ),
9205  point_south );
9206  }
9207 
9208  wnoutrefresh( w_monsters_border );
9209  wnoutrefresh( w_monster_info_border );
9210  wnoutrefresh( w_monsters );
9211  wnoutrefresh( w_monster_info );
9212  }
9213  } );
9214 
9215  std::optional<tripoint> trail_start;
9216  std::optional<tripoint> trail_end;
9217  bool trail_end_x = false;
9218  shared_ptr_fast<draw_callback_t> trail_cb = create_trail_callback( trail_start, trail_end,
9219  trail_end_x );
9220  add_draw_callback( trail_cb );
9221  const int recmax = static_cast<int>( monster_list.size() );
9222  const int scroll_rate = recmax > 20 ? 10 : 3;
9223 
9224  do {
9225  if( navigate_ui_list( action, iActive, scroll_rate, recmax, true ) ) {
9226  } else if( action == "NEXT_TAB" || action == "PREV_TAB" ) {
9227  u.view_offset = stored_view_offset;
9229  } else if( action == "zoom_in" ) {
9230  zoom_in();
9232  } else if( action == "zoom_out" ) {
9233  zoom_out();
9235  } else if( action == "SAFEMODE_BLACKLIST_REMOVE" ) {
9236  const monster *m = dynamic_cast<monster *>( cCurMon );
9237  const std::string monName = ( m != nullptr ) ? m->name() : "human";
9238 
9239  if( get_safemode().has_rule( monName, Creature::Attitude::ANY ) ) {
9241  }
9242  } else if( action == "SAFEMODE_BLACKLIST_ADD" ) {
9243  if( !get_safemode().empty() ) {
9244  const monster *m = dynamic_cast<monster *>( cCurMon );
9245  const std::string monName = ( m != nullptr ) ? m->name() : "human";
9246 
9247  get_safemode().add_rule( monName, Creature::Attitude::ANY, get_option<int>( "SAFEMODEPROXIMITY" ),
9249  }
9250  } else if( action == "look" ) {
9251  hide_ui = true;
9252  ui.mark_resize();
9253  look_around();
9254  hide_ui = false;
9255  ui.mark_resize();
9256  } else if( action == "fire" ) {
9257  if( cCurMon != nullptr && rl_dist( u.pos(), cCurMon->pos() ) <= max_gun_range ) {
9258  u.last_target = shared_from( *cCurMon );
9259  u.recoil = MAX_RECOIL;
9260  u.view_offset = stored_view_offset;
9261  return game::vmenu_ret::FIRE;
9262  }
9263  }
9264 
9265  if( iActive >= 0 && static_cast<size_t>( iActive ) < monster_list.size() ) {
9266  cCurMon = monster_list[iActive];
9267  iActivePos = cCurMon->pos() - u.pos();
9268  centerlistview( iActivePos, width );
9269  trail_start = u.pos();
9270  trail_end = cCurMon->pos();
9271  // Actually accessed from the terrain overlay callback `trail_cb` in the
9272  // call to `ui_manager::redraw`.
9273  //NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
9274  trail_end_x = false;
9275  } else {
9276  cCurMon = nullptr;
9277  iActivePos = tripoint_zero;
9278  u.view_offset = stored_view_offset;
9279  trail_start = trail_end = std::nullopt;
9280  }
9282 
9284 
9285  action = ctxt.handle_input();
9286  } while( action != "QUIT" );
9287 
9288  u.view_offset = stored_view_offset;
9289 
9290  return game::vmenu_ret::QUIT;
9291 }
double recoil
Definition: character.h:1117
weak_ptr_fast< Creature > last_target
Definition: character.h:2761
nc_color symbol_color() const override
Creature symbol background color.
Definition: character.cpp:5745
static const std::pair< translation, nc_color > & get_attitude_ui_data(Attitude att)
Creature Attitude as String and color.
Definition: creature.cpp:3088
bool sees(const Creature &critter) const override
The functions check whether this creature can see the target.
Definition: creature.cpp:358
virtual int get_hp_max(const bodypart_id &bp) const
Definition: creature.cpp:2765
Attitude
Simplified attitude towards any creature: hostile - hate, want to kill, etc.
Definition: creature.h:352
virtual int get_hp(const bodypart_id &bp) const
Definition: creature.cpp:2748
virtual int print_info(const catacurses::window &w, int vStart, int vLines, int column) const =0
Write information about this creature.
virtual nc_color basic_symbol_color() const =0
Creature symbol color.
shared_ptr_fast< T > shared_from(const T &critter)
Returns a shared pointer to the given critter (which can be of any of the subclasses of Creature).
Definition: game.cpp:5125
bool bVMonsterLookFire
Definition: game.h:1165
int gun_range(const Character *p) const
The weapons range in map squares.
Definition: item.cpp:10648
npc_attitude get_attitude() const override
Definition: npc.cpp:3546
void remove_rule(std::string_view rule_in, Creature::Attitude attitude_in)
bool has_rule(std::string_view rule_in, Creature::Attitude attitude_in)
static nc_color color(const T_t &t)
static const trait_id trait_INATTENTIVE("INATTENTIVE")
constexpr double MAX_RECOIL
std::string npc_attitude_name(npc_attitude att)
Definition: npc.cpp:2959
size_t shortcut_print(const catacurses::window &w, const point &p, nc_color text_color, nc_color shortcut_color, const std::string &fmt)
Definition: output.cpp:2587
int right_print(const catacurses::window &w, const int line, const int right_indent, const nc_color &FG, const std::string &text)
Definition: output.cpp:574
std::pair< std::string, nc_color > get_hp_bar(const int cur_hp, const int max_hp, const bool is_mon)
Definition: output.cpp:2657
bool navigate_ui_list(const std::string &action, V &val, int page_delta, S size, bool wrap)
Helper for typical UI list navigation with wrap-around Handles up, down, scroll_up and _down,...
Definition: ui.cpp:1421

References _, action, add_draw_callback(), safemode::add_rule(), Creature::ANY, Creature::basic_symbol_color(), BLACKLISTED, bVMonsterLookFire, c_light_gray, c_light_green, c_magenta, c_white, c_yellow, calcStartPos(), centerlistview(), CHANGE_TAB, color(), create_trail_callback(), direction_from(), direction_name_short(), Creature::disp_name(), draw_custom_border(), draw_scrollbar(), FIRE, npc::get_attitude(), Creature::get_attitude_ui_data(), Creature::get_hp(), get_hp_bar(), Creature::get_hp_max(), get_safemode(), Character::get_wielded_item(), catacurses::getmaxy(), item::gun_range(), input_context::handle_input(), safemode::has_rule(), Character::has_trait(), hilite(), invalidate_main_ui_adaptor(), Character::last_target, LINE_XOXO, LINE_XOXX, LINE_XXXO, look_around(), m, mark_main_ui_adaptor_resize(), MAX_RECOIL, catacurses::mvwprintw(), mvwprintz(), map::name(), navigate_ui_list(), catacurses::newwin(), npc_attitude_name(), safemode::npc_type_name(), point, point_east, point_south, point_zero, Creature::pos(), input_context::press_x(), Creature::print_info(), QUIT, Character::recoil, ui_manager::redraw(), input_context::register_action(), input_context::register_navigate_ui_list(), safemode::remove_rule(), right_print(), rl_dist(), Creature::sees(), shared_from(), shortcut_print(), string_format(), Character::symbol_color(), TERMX, TERMY, trait_INATTENTIVE, trim_and_print(), tripoint_zero, u, utf8_width(), Character::view_offset, catacurses::werase(), catacurses::wnoutrefresh(), catacurses::wprintw(), wprintz(), zoom_in(), and zoom_out().

◆ load() [1/2]

bool game::load ( const save_t name)
private

Definition at line 3070 of file game.cpp.

3071 {
3072  loading_ui ui( true );
3073  ui.new_context( _( "Loading the save…" ) );
3074 
3075  const cata_path worldpath = PATH_INFO::world_base_save_path_path();
3076  const cata_path save_file_path = PATH_INFO::world_base_save_path_path() /
3077  ( name.base_path() + SAVE_EXTENSION );
3078 
3079  bool abort = false;
3080 
3081  using named_entry = std::pair<std::string, std::function<void()>>;
3082  const std::vector<named_entry> entries = {{
3083  {
3084  _( "Master save" ), [&]()
3085  {
3086  // Now load up the master game data; factions (and more?)
3087  load_master();
3088  }
3089  },
3090  {
3091  _( "Character save" ), [&]()
3092  {
3093 
3094  u = avatar();
3095  u.set_save_id( name.decoded_name() );
3096  if( !read_from_file(
3097  save_file_path,
3098  [this, &save_file_path]( std::istream & is ) {
3099  unserialize( is, save_file_path );
3100  } ) ) {
3101  abort = true;
3102  }
3103  }
3104  },
3105  {
3106  _( "Map memory" ), [&]()
3107  {
3108  u.load_map_memory();
3109  }
3110  },
3111  {
3112  _( "Diary" ), [&]()
3113  {
3114  u.get_avatar_diary()->load();
3115  }
3116  },
3117  {
3118  _( "Memorial" ), [&]()
3119  {
3120  const cata_path log_filename =
3121  worldpath / ( name.base_path() + SAVE_EXTENSION_LOG );
3123  log_filename.get_unrelative_path(),
3124  [this]( std::istream & is ) {
3125  memorial().load( is );
3126  } );
3127  }
3128  },
3129  {
3130  _( "Finalizing" ), [&]()
3131  {
3132 
3133 #if defined(__ANDROID__)
3134  const cata_path shortcuts_filename =
3135  worldpath / ( name.base_path() + SAVE_EXTENSION_SHORTCUTS );
3136  if( file_exist( shortcuts_filename ) ) {
3137  load_shortcuts( shortcuts_filename );
3138  }
3139 #endif
3140 
3141  // Now that the player's worn items are updated, their sight limits need to be
3142  // recalculated. (This would be cleaner if u.worn were private.)
3144 
3145  if( !gamemode ) {
3146  gamemode = std::make_unique<special_game>();
3147  }
3148 
3149  safe_mode = get_option<bool>( "SAFEMODE" ) ? SAFE_MODE_ON : SAFE_MODE_OFF;
3150  mostseen = 0; // ...and mostseen is 0, we haven't seen any monsters yet.
3151 
3152  init_autosave();
3153  get_auto_pickup().load_character(); // Load character auto pickup rules
3154  get_auto_notes_settings().load( true ); // Load character auto notes settings
3155  get_safemode().load_character(); // Load character safemode rules
3156  zone_manager::get_manager().load_zones(); // Load character world zones
3158  PATH_INFO::world_base_save_path_path() / "uistate.json",
3159  []( const JsonValue & jsin ) {
3160  uistate.deserialize( jsin.get_object() );
3161  } );
3162  reload_npcs();
3165  validate_camps();
3167  update_map( u );
3168  for( item *&e : u.inv_dump() ) {
3169  e->set_owner( get_player_character() );
3170  }
3171  // legacy, needs to be here as we access the map.
3172  if( !u.getID().is_valid() ) {
3173  // player does not have a real id, so assign a new one,
3174  u.setID( assign_npc_id() );
3175  // The vehicle stores the IDs of the boarded players, so update it, too.
3176  if( u.in_vehicle ) {
3177  if( const std::optional<vpart_reference> vp = m.veh_at(
3178  u.pos() ).part_with_feature( "BOARDABLE", true ) ) {
3179  vp->part().passenger_id = u.getID();
3180  }
3181  }
3182  }
3183 
3184  // populate calendar caches now, after active world is set, but before we do
3185  // anything else, to ensure they pick up the correct value from the save's
3186  // worldoptions
3187  calendar::set_eternal_season( ::get_option<bool>( "ETERNAL_SEASON" ) );
3188  calendar::set_season_length( ::get_option<int>( "SEASON_LENGTH" ) );
3189 
3191  ::get_option<std::string>( "ETERNAL_TIME_OF_DAY" ) == "night" );
3193  ::get_option<std::string>( "ETERNAL_TIME_OF_DAY" ) == "day" );
3194 
3195  u.reset();
3197  u.enchantment_cache->activate_passive( u );
3199  time_of_last_load = std::chrono::steady_clock::now();
3200  time_played_at_last_load = std::chrono::seconds( 0 );
3201  std::optional<event_multiset::summaries_type::value_type> last_save =
3203  if( last_save ) {
3204  auto time_played_it = last_save->first.find( "total_time_played" );
3205  if( time_played_it != last_save->first.end() &&
3206  time_played_it->second.type() == cata_variant_type::chrono_seconds ) {
3208  time_played_it->second.get<std::chrono::seconds>();
3209  }
3210  }
3211 
3213  // recalculate light level for correctly resuming crafting and disassembly
3214  m.build_map_cache( m.get_abs_sub().z() );
3215  }
3216  },
3217  }
3218  };
3219 
3220  for( const named_entry &e : entries ) {
3221  ui.add_entry( e.first );
3222  }
3223 
3224  ui.show();
3225  for( const named_entry &e : entries ) {
3226  e.second();
3227  if( abort ) {
3228  return false;
3229  }
3230  ui.proceed();
3231  }
3232 
3233  return true;
3234 }
bool read_from_file(const cata_path &path, const std::function< void(std::istream &)> &reader)
bool read_from_file_optional_json(const cata_path &path, const std::function< void(const JsonValue &)> &reader)
bool read_from_file_optional(const std::string &path, const std::function< void(std::istream &)> &reader)
void setID(character_id i, bool force=false)
sets the ID, will only succeed when the current id is not valid allows forcing a -1 id which is requi...
Definition: character.cpp:641
std::vector< item * > inv_dump()
Definition: character.cpp:8656
void recalc_sight_limits()
Modifies the player's sight values Must be called when any of the following change: This must be call...
Definition: character.cpp:2517
void recalculate_enchantment_cache()
Definition: character.cpp:7750
void reset() override
Handles stat and bonus reset.
Definition: character.cpp:3834
pimpl< enchant_cache > enchantment_cache
Definition: character.h:4105
JsonObject get_object() const
void load(bool bCharacter)
Definition: auto_note.cpp:108
void set_save_id(const std::string &id)
Definition: avatar.h:131
void load_map_memory()
Definition: avatar.cpp:271
One of the problems of filesystem paths is they lack contextual awareness of 'where' they are.
Definition: cata_path.h:34
fs::path get_unrelative_path() const
Definition: cata_path.h:65
bool is_valid() const
Definition: character_id.h:17
void load()
Definition: diary.cpp:747
std::optional< summaries_type::value_type > last() const
void validate_linked_vehicles()
validate towed vehicles so they get linked up again after a load
Definition: game.cpp:1745
void unserialize(std::istream &fin, const cata_path &path)
Definition: savegame.cpp:205
std::chrono::time_point< std::chrono::steady_clock > time_of_last_load
Definition: game.h:1173
void reload_npcs()
Unloads, then loads the NPCs.
Definition: game.cpp:1264
void validate_camps()
validate camps to ensure they are on the overmap list
Definition: game.cpp:1803
std::chrono::seconds time_played_at_last_load
Definition: game.h:1171
void load_master()
Definition: game.cpp:3038
void validate_mounted_npcs()
Definition: game.cpp:1760
character_id assign_npc_id()
Definition: game.cpp:4466
void init_autosave()
Definition: game.cpp:13038
void validate_npc_followers()
validate list of followers to account for overmap buffers
Definition: game.cpp:1779
void load_character()
event_multiset & get_events(event_type)
void deserialize(const JsonObject &jo)
void load_zones(std::string const &suffix={})
Definition: clzones.cpp:1712
bool file_exist(const std::string &path)
Definition: filesystem.cpp:115
const char * getVersionString()
Definition: version.cpp:15
cata_path world_base_save_path_path()
Definition: game.cpp:13266
void set_season_length(int dur)
Definition: calendar.cpp:731
void set_eternal_season(bool is_eternal_season)
Definition: calendar.cpp:719
void set_eternal_night(bool is_eternal_night)
Definition: calendar.cpp:723
void set_eternal_day(bool is_eternal_day)
Definition: calendar.cpp:727
void load_existing_character(Character &you)
Load any new eocs that don't exist in the save.
std::string name(type dir)
Get Human readable name of a direction.
Definition: overmap.cpp:6412
const std::string SAVE_EXTENSION_LOG(".log")
const std::string SAVE_EXTENSION(".sav")
const std::string SAVE_EXTENSION_SHORTCUTS(".shortcuts")

References _, abort, assign_npc_id(), map::build_map_cache(), chrono_seconds, uistatedata::deserialize(), Character::enchantment_cache, events(), file_exist(), game_load, game_save, gamemode, map::get_abs_sub(), get_auto_notes_settings(), get_auto_pickup(), avatar::get_avatar_diary(), stats_tracker::get_events(), zone_manager::get_manager(), JsonValue::get_object(), get_player_character, get_safemode(), cata_path::get_unrelative_path(), Character::getID(), getVersionString(), Character::in_vehicle, init_autosave(), Character::inv_dump(), character_id::is_valid(), event_multiset::last(), diary::load(), auto_notes::auto_note_settings::load(), auto_pickup::player_settings::load_character(), safemode::load_character(), effect_on_conditions::load_existing_character(), avatar::load_map_memory(), load_master(), zone_manager::load_zones(), m, mostseen, om_direction::name(), optional_vpart_position::part_with_feature(), Creature::pos(), read_from_file(), read_from_file_optional(), read_from_file_optional_json(), Character::recalc_sight_limits(), Character::recalculate_enchantment_cache(), reload_npcs(), Character::reset(), safe_mode, SAFE_MODE_OFF, SAFE_MODE_ON, SAVE_EXTENSION(), SAVE_EXTENSION_LOG(), SAVE_EXTENSION_SHORTCUTS(), event_bus::send(), calendar::set_eternal_day(), calendar::set_eternal_night(), calendar::set_eternal_season(), avatar::set_save_id(), calendar::set_season_length(), Character::setID(), stats(), time_of_last_load, time_played_at_last_load, u, uistate, unserialize(), update_map(), validate_camps(), validate_linked_vehicles(), validate_mounted_npcs(), validate_npc_followers(), map::veh_at(), PATH_INFO::world_base_save_path_path(), and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

◆ load() [2/2]

bool game::load ( const std::string &  world)

Attempt to load first valid save (if any) in world.

Definition at line 3046 of file game.cpp.

3047 {
3048  world_generator->init();
3049  WORLD *const wptr = world_generator->get_world( world );
3050  if( !wptr ) {
3051  return false;
3052  }
3053  if( wptr->world_saves.empty() ) {
3054  debugmsg( "world '%s' contains no saves", world );
3055  return false;
3056  }
3057 
3058  try {
3059  world_generator->set_active_world( wptr );
3060  g->setup();
3061  g->load( wptr->world_saves.front() );
3062  } catch( const std::exception &err ) {
3063  debugmsg( "cannot load world '%s': %s", world, err.what() );
3064  return false;
3065  }
3066 
3067  return true;
3068 }
std::vector< save_t > world_saves
Definition: worldfactory.h:64

References debugmsg, g, world_generator, and WORLD::world_saves.

◆ load_core_data()

void game::load_core_data ( loading_ui ui)

Loads core dynamic data.

May throw.

Definition at line 580 of file game.cpp.

581 {
582  // core data can be loaded only once and must be first
583  // anyway.
585 
587 }
void unload_data()
Deletes and unloads all the data previously loaded with load_data_from_path.
Definition: init.cpp:548
cata_path jsondir()
Definition: path_info.cpp:346

References DynamicDataLoader::get_instance(), PATH_INFO::jsondir(), load_data_from_dir(), and DynamicDataLoader::unload_data().

Referenced by check_mod_data(), and setup().

◆ load_data_from_dir()

void game::load_data_from_dir ( const cata_path path,
const std::string &  src,
loading_ui ui 
)
protected

Loads dynamic data from the given directory.

May throw.

Definition at line 589 of file game.cpp.

590 {
592 }
void load_data_from_path(const cata_path &path, const std::string &src, loading_ui &ui)
Load all data from json files located in the path (recursive).
Definition: init.cpp:496

References DynamicDataLoader::get_instance(), and DynamicDataLoader::load_data_from_path().

Referenced by check_mod_data(), load_core_data(), and load_packs().

◆ load_map()

void game::load_map ( const tripoint_abs_sm pos_sm,
bool  pump_events = false 
)

Load the main map at given location, see map::load, in global, absolute submap coordinates.

Parameters
pump_eventsIf true, handle window events during loading. If you set this to true, do ensure that the map is not accessed before this function returns (for example, UIs that draw the map should be disabled).

Definition at line 843 of file game.cpp.

845 {
846  m.load( pos_sm, true, pump_events );
847 }
void load(const tripoint_abs_sm &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:7894

References map::load(), and m.

Referenced by place_player_overmap(), start_game(), and unserialize().

◆ load_master()

void game::load_master ( )
private

Definition at line 3038 of file game.cpp.

3039 {
3041  read_from_file_optional( datafile, [this, &datafile]( std::istream & is ) {
3042  unserialize_master( datafile, is );
3043  } );
3044 }
void unserialize_master(const cata_path &file_name, std::istream &fin)
Definition: savegame.cpp:1408
enum holiday int const std::string SAVE_MASTER("master.gsav")

References read_from_file_optional(), SAVE_MASTER(), unserialize_master(), and PATH_INFO::world_base_save_path_path().

Referenced by load(), and start_game().

◆ load_npcs()

void game::load_npcs ( )

Makes any nearby NPCs on the overmap active.

Definition at line 1188 of file game.cpp.

1189 {
1190  const int radius = HALF_MAPSIZE - 1;
1191  const tripoint_abs_sm abs_sub( get_map().get_abs_sub() );
1192  const half_open_rectangle<point_abs_sm> map_bounds( abs_sub.xy(), abs_sub.xy() + point( MAPSIZE,
1193  MAPSIZE ) );
1194  // uses submap coordinates
1195  std::vector<shared_ptr_fast<npc>> just_added;
1196  for( const auto &temp : overmap_buffer.get_npcs_near_player( radius ) ) {
1197  const character_id &id = temp->getID();
1198  const auto found = std::find_if( critter_tracker->active_npc.begin(),
1199  critter_tracker->active_npc.end(),
1200  [id]( const shared_ptr_fast<npc> &n ) {
1201  return n->getID() == id;
1202  } );
1203  if( found != critter_tracker->active_npc.end() ) {
1204  continue;
1205  }
1206  if( temp->is_active() ) {
1207  continue;
1208  }
1209  if( temp->has_companion_mission() ) {
1210  continue;
1211  }
1212 
1213  const tripoint_abs_sm sm_loc = temp->global_sm_location();
1214  // NPCs who are out of bounds before placement would be pushed into bounds
1215  // This can cause NPCs to teleport around, so we don't want that
1216  if( !map_bounds.contains( sm_loc.xy() ) ) {
1217  continue;
1218  }
1219 
1220  add_msg_debug( debugmode::DF_NPC, "game::load_npcs: Spawning static NPC, %s %s",
1221  abs_sub.to_string_writable(), sm_loc.to_string_writable() );
1222  temp->place_on_map();
1223  if( !m.inbounds( temp->pos() ) ) {
1224  continue;
1225  }
1226  // In the rare case the npc was marked for death while
1227  // it was on the overmap. Kill it.
1228  if( temp->marked_for_death ) {
1229  temp->die( nullptr );
1230  } else {
1231  critter_tracker->active_npc.push_back( temp );
1232  just_added.push_back( temp );
1233  }
1234  }
1235 
1236  for( const auto &npc : just_added ) {
1237  npc->on_load();
1238  }
1239 
1240  npcs_dirty = false;
1241 }
std::string to_string_writable() const
Definition: coordinates.h:124
bool npcs_dirty
Has a NPC been spawned since last load?
Definition: game.h:1182
void on_load()
Retroactively update npc.
Definition: npc.cpp:3070
constexpr int MAPSIZE
@ DF_NPC
Definition: debug.h:267

References add_msg_debug, half_open_rectangle< Point, >::contains(), critter_tracker, debugmode::DF_NPC, get_map, overmapbuffer::get_npcs_near_player(), HALF_MAPSIZE, map::inbounds(), m, MAPSIZE, npcs_dirty, npc::on_load(), overmap_buffer, temp, coords::coord_point_base< Point >::to_string_writable(), and coords::coord_point< Point, Origin, Scale, InBounds >::xy().

Referenced by perhaps_add_random_npc(), place_player_overmap(), reload_npcs(), save_cyborg(), spawn_hallucination(), spawn_npc(), start_game(), and update_map().

◆ load_packs()

bool game::load_packs ( const std::string &  msg,
const std::vector< mod_id > &  packs,
loading_ui ui 
)

Load content packs.

Parameters
msgstring to display whilst loading prompt
packscontent packs to load in correct dependent order
uistructure for load progress display
Returns
true if all packs were found, false if any were missing

Definition at line 3271 of file game.cpp.

3272 {
3273  ui.new_context( msg );
3274  std::vector<mod_id> missing;
3275  std::vector<mod_id> available;
3276 
3277  for( const mod_id &e : packs ) {
3278  if( e.is_valid() ) {
3279  available.emplace_back( e );
3280  ui.add_entry( e->name() );
3281  } else {
3282  missing.push_back( e );
3283  }
3284  }
3285 
3286  ui.show();
3287  for( const auto &e : available ) {
3288  const MOD_INFORMATION &mod = *e;
3289  restore_on_out_of_scope<check_plural_t> restore_check_plural( check_plural );
3290  if( mod.ident.str() == "test_data" ) {
3292  }
3293  load_data_from_dir( mod.path, mod.ident.str(), ui );
3294 
3295  ui.proceed();
3296  }
3297 
3298  for( const auto &e : missing ) {
3299  debugmsg( "unknown content %s", e.c_str() );
3300  }
3301 
3302  return missing.empty();
3303 }
check_plural_t check_plural

References available, string_id< T >::c_str(), check_plural, debugmsg, string_id< T >::is_valid(), load_data_from_dir(), MOD_INFORMATION::name(), and none.

◆ load_static_data()

void game::load_static_data ( )

Loads static data that does not depend on mods or similar.

Definition at line 468 of file game.cpp.

469 {
470  // UI stuff, not mod-specific per definition
471  inp_mngr.init(); // Load input config JSON
472  // Init mappings for loading the json stuff
474  fullscreen = false;
475  was_fullscreen = false;
476  show_panel_adm = false;
477 
478  // These functions do not load stuff from json.
479  // The content they load/initialize is hardcoded into the program.
480  // Therefore they can be loaded here.
481  // If this changes (if they load data from json), they have to
482  // be moved to game::load_mod or game::load_core_data
483 
485  get_auto_notes_settings().load( false );
487 }
bool was_fullscreen
Definition: game.h:1137
void init()
Initializes the input manager, aka loads the input mapping configuration JSON.
Definition: input.cpp:163
void load_global()

References fullscreen, get_auto_notes_settings(), get_auto_pickup(), DynamicDataLoader::get_instance(), get_safemode(), input_manager::init(), inp_mngr, auto_notes::auto_note_settings::load(), auto_pickup::player_settings::load_global(), safemode::load_global(), show_panel_adm, and was_fullscreen.

◆ load_world_modfiles()

void game::load_world_modfiles ( loading_ui ui)

Loads core data and mods from the active world.

May throw.

Definition at line 3236 of file game.cpp.

3237 {
3238  auto &mods = world_generator->active_world->active_mod_order;
3239 
3240  // remove any duplicates whilst preserving order (fixes #19385)
3241  std::set<mod_id> found;
3242  mods.erase( std::remove_if( mods.begin(), mods.end(), [&found]( const mod_id & e ) {
3243  if( found.count( e ) ) {
3244  return true;
3245  } else {
3246  found.insert( e );
3247  return false;
3248  }
3249  } ), mods.end() );
3250 
3251  // require at least one core mod (saves before version 6 may implicitly require dda pack)
3252  if( std::none_of( mods.begin(), mods.end(), []( const mod_id & e ) {
3253  return e->core;
3254 } ) ) {
3255  mods.insert( mods.begin(), MOD_INFORMATION_dda );
3256  }
3257 
3258  // this code does not care about mod dependencies,
3259  // it assumes that those dependencies are static and
3260  // are resolved during the creation of the world.
3261  // That means world->active_mod_order contains a list
3262  // of mods in the correct order.
3263  load_packs( _( "Loading files" ), mods, ui );
3264 
3265  // Load additional mods from that world-specific folder
3267 
3269 }
bool load_packs(const std::string &msg, const std::vector< mod_id > &packs, loading_ui &ui)
Load content packs.
Definition: game.cpp:3271
static const mod_id MOD_INFORMATION_dda("dda")
std::string mods(item const &it, unsigned int, segment_bitset const &)
Definition: item_tname.cpp:152

References anonymous_namespace{item_tname.cpp}::mods(), and world_generator.

Referenced by setup().

◆ look_around() [1/3]

std::optional< tripoint > game::look_around ( )

Definition at line 7639 of file game.cpp.

7640 {
7641  tripoint center = u.pos() + u.view_offset;
7642  look_around_result result = look_around( /*show_window=*/true, center, center, false, false,
7643  false );
7644  return result.position;
7645 }
std::optional< tripoint > position
Definition: game.h:113

References center, Creature::pos(), look_around_result::position, u, and Character::view_offset.

Referenced by chat(), list_monsters(), look_around(), peek(), and zones_manager().

◆ look_around() [2/3]

look_around_result game::look_around ( bool  show_window,
tripoint center,
const tripoint start_point,
bool  has_first_point,
bool  select_zone,
bool  peeking,
bool  is_moving_zone = false,
const tripoint end_point = tripoint_zero,
bool  change_lv = true 
)
Parameters
show_windowdisplay the info window that holds the tile information in the position.
centerused to calculate the u.view_offset, could center the screen to the position it represents
start_pointthe start point of the targeting zone, also the initial local position of the cursor
has_first_pointshould be true if the first point has been selected when editing the zone
select_zonetrue if the zone is being edited
peekingdetermines if the player is peeking
is_moving_zonetrue if the zone is being moved, false by default
end_pointthe end point of the targeting zone, only used if is_moving_zone is true, default is tripoint_zero
change_lvdetermines allow if change z-level
Returns
look_around_result

Definition at line 7649 of file game.cpp.

7652 {
7653  bVMonsterLookFire = false;
7654 
7656 
7657  // TODO: fix point types
7658  tripoint_bub_ms lp( is_moving_zone ? ( start_point + end_point ) / 2 : start_point ); // cursor
7659  int &lx = lp.x();
7660  int &ly = lp.y();
7661  int &lz = lp.z();
7662 
7663  int soffset = get_option<int>( "FAST_SCROLL_OFFSET" );
7664  static bool fast_scroll = false;
7665 
7666  std::unique_ptr<ui_adaptor> ui;
7667  catacurses::window w_info;
7668  if( show_window ) {
7669  ui = std::make_unique<ui_adaptor>();
7670  ui->on_screen_resize( [&]( ui_adaptor & ui ) {
7671  int panel_width = panel_manager::get_manager().get_current_layout().panels().begin()->get_width();
7672  int height = pixel_minimap_option ? TERMY - getmaxy( w_pixel_minimap ) : TERMY;
7673 
7674  // If particularly small, base height on panel width irrespective of other elements.
7675  // Value here is attempting to get a square-ish result assuming 1x2 proportioned font.
7676  if( height < panel_width / 2 ) {
7677  height = panel_width / 2;
7678  }
7679 
7680  int la_y = 0;
7681  int la_x = TERMX - panel_width;
7682  std::string position = get_option<std::string>( "LOOKAROUND_POSITION" );
7683  if( position == "left" ) {
7684  if( get_option<std::string>( "SIDEBAR_POSITION" ) == "right" ) {
7686  } else {
7687  la_x = panel_manager::get_manager().get_width_left() - panel_width;
7688  }
7689  }
7690  int la_h = height;
7691  int la_w = panel_width;
7692  w_info = catacurses::newwin( la_h, la_w, point( la_x, la_y ) );
7693 
7694  ui.position_from_window( w_info );
7695  } );
7696  ui->mark_resize();
7697  }
7698 
7699  dbg( D_PEDANTIC_INFO ) << ": calling handle_input()";
7700 
7701  std::string action;
7702  input_context ctxt( "LOOK" );
7703  ctxt.set_iso( true );
7704  ctxt.register_directions();
7705  ctxt.register_action( "COORDINATE" );
7706  if( change_lv && fov_3d_z_range > 0 ) {
7707  ctxt.register_action( "LEVEL_UP" );
7708  ctxt.register_action( "LEVEL_DOWN" );
7709  }
7710  ctxt.register_action( "TOGGLE_FAST_SCROLL" );
7711  ctxt.register_action( "CHANGE_MONSTER_NAME" );
7712  ctxt.register_action( "EXTENDED_DESCRIPTION" );
7713  ctxt.register_action( "SELECT" );
7714  if( peeking ) {
7715  ctxt.register_action( "throw_blind" );
7716  }
7717  if( !select_zone ) {
7718  ctxt.register_action( "TRAVEL_TO" );
7719  ctxt.register_action( "LIST_ITEMS" );
7720  }
7721  ctxt.register_action( "MOUSE_MOVE" );
7722  ctxt.register_action( "CENTER" );
7723 
7724  ctxt.register_action( "debug_scent" );
7725  ctxt.register_action( "debug_scent_type" );
7726  ctxt.register_action( "debug_temp" );
7727  ctxt.register_action( "debug_visibility" );
7728  ctxt.register_action( "debug_lighting" );
7729  ctxt.register_action( "debug_radiation" );
7730  ctxt.register_action( "debug_hour_timer" );
7731  ctxt.register_action( "CONFIRM" );
7732  ctxt.register_action( "QUIT" );
7733  ctxt.register_action( "HELP_KEYBINDINGS" );
7734  ctxt.register_action( "zoom_out" );
7735  ctxt.register_action( "zoom_in" );
7736  ctxt.register_action( "toggle_pixel_minimap" );
7737 
7738  const int old_levz = m.get_abs_sub().z();
7739  const int min_levz = std::max( old_levz - fov_3d_z_range, -OVERMAP_DEPTH );
7740  const int max_levz = std::min( old_levz + fov_3d_z_range, OVERMAP_HEIGHT );
7741 
7742  m.update_visibility_cache( old_levz );
7744 
7745  bool blink = true;
7746  look_around_result result;
7747 
7748  shared_ptr_fast<draw_callback_t> ter_indicator_cb;
7749 
7750  if( show_window && ui ) {
7751  ui->on_redraw( [&]( const ui_adaptor & ) {
7752  werase( w_info );
7753  draw_border( w_info );
7754 
7755  center_print( w_info, 0, c_white, string_format( _( "< <color_green>Look around</color> >" ) ) );
7756 
7757  creature_tracker &creatures = get_creature_tracker();
7758  monster *const mon = creatures.creature_at<monster>( lp, true );
7759  if( mon && u.sees( *mon ) ) {
7760  std::string mon_name_text = string_format( _( "%s - %s" ),
7761  ctxt.get_desc( "CHANGE_MONSTER_NAME" ),
7762  ctxt.get_action_name( "CHANGE_MONSTER_NAME" ) );
7763  mvwprintz( w_info, point( 1, getmaxy( w_info ) - 2 ), c_red, mon_name_text );
7764  }
7765 
7766  std::string fast_scroll_text = string_format( _( "%s - %s" ),
7767  ctxt.get_desc( "TOGGLE_FAST_SCROLL" ),
7768  ctxt.get_action_name( "TOGGLE_FAST_SCROLL" ) );
7769  mvwprintz( w_info, point( 1, getmaxy( w_info ) - 1 ), fast_scroll ? c_light_green : c_green,
7770  fast_scroll_text );
7771 
7772  if( !ctxt.keys_bound_to( "toggle_pixel_minimap" ).empty() ) {
7773  std::string pixel_minimap_text = string_format( _( "%s - %s" ),
7774  ctxt.get_desc( "toggle_pixel_minimap" ),
7775  ctxt.get_action_name( "toggle_pixel_minimap" ) );
7776  right_print( w_info, getmaxy( w_info ) - 1, 1, pixel_minimap_option ? c_light_green : c_green,
7777  pixel_minimap_text );
7778  }
7779 
7780  int first_line = 1;
7781  const int last_line = getmaxy( w_info ) - 2;
7782  // TODO: fix point types
7783  pre_print_all_tile_info( lp.raw(), w_info, first_line, last_line, cache );
7784 
7785  wnoutrefresh( w_info );
7786  } );
7787  ter_indicator_cb = make_shared_fast<draw_callback_t>( [&]() {
7788  // TODO: fix point types
7789  draw_look_around_cursor( lp.raw(), cache );
7790  } );
7791  add_draw_callback( ter_indicator_cb );
7792  }
7793 
7794  std::optional<tripoint> zone_start;
7795  std::optional<tripoint> zone_end;
7796  bool zone_blink = false;
7797  bool zone_cursor = true;
7798  shared_ptr_fast<draw_callback_t> zone_cb = create_zone_callback( zone_start, zone_end, zone_blink,
7799  zone_cursor, is_moving_zone );
7800  add_draw_callback( zone_cb );
7801 
7802  is_looking = true;
7803  const tripoint prev_offset = u.view_offset;
7804 #if defined(TILES)
7805  const int prev_tileset_zoom = tileset_zoom;
7806  while( is_moving_zone && square_dist( start_point, end_point ) > 256 / get_zoom() &&
7807  get_zoom() != 4 ) {
7808  zoom_out();
7809  }
7811 #endif
7812  do {
7813  u.view_offset = center - u.pos();
7814  if( select_zone ) {
7815  if( has_first_point ) {
7816  zone_start = start_point;
7817  // TODO: fix point types
7818  zone_end = lp.raw();
7819  } else {
7820  // TODO: fix point types
7821  zone_start = lp.raw();
7822  zone_end = std::nullopt;
7823  }
7824  // Actually accessed from the terrain overlay callback `zone_cb` in the
7825  // call to `ui_manager::redraw`.
7826  //NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
7827  zone_blink = blink;
7828  }
7829 
7830  if( is_moving_zone ) {
7831  // TODO: fix point types
7832  zone_start = lp.raw() - ( start_point + end_point ) / 2 + start_point;
7833  // TODO: fix point types
7834  zone_end = lp.raw() - ( start_point + end_point ) / 2 + end_point;
7835  // Actually accessed from the terrain overlay callback `zone_cb` in the
7836  // call to `ui_manager::redraw`.
7837  //NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
7838  zone_blink = blink;
7839  }
7840 #if defined(TILES)
7841  // Mark cata_tiles draw caches as dirty
7842  tilecontext->set_draw_cache_dirty();
7843 #endif
7846 
7847  if( ( select_zone && has_first_point ) || is_moving_zone ) {
7848  ctxt.set_timeout( get_option<int>( "BLINK_SPEED" ) );
7849  }
7850 
7851  //Wait for input
7852  // only specify a timeout here if "EDGE_SCROLL" is enabled
7853  // otherwise use the previously set timeout
7854  const tripoint edge_scroll = mouse_edge_scrolling_terrain( ctxt );
7855  const int scroll_timeout = get_option<int>( "EDGE_SCROLL" );
7856  const bool edge_scrolling = edge_scroll != tripoint_zero && scroll_timeout >= 0;
7857  if( edge_scrolling ) {
7858  action = ctxt.handle_input( scroll_timeout );
7859  } else {
7860  action = ctxt.handle_input();
7861  }
7862  if( ( action == "LEVEL_UP" || action == "LEVEL_DOWN" || action == "MOUSE_MOVE" ||
7863  ctxt.get_direction( action ) ) && ( ( select_zone && has_first_point ) || is_moving_zone ) ) {
7864  blink = true; // Always draw blink symbols when moving cursor
7865  } else if( action == "TIMEOUT" ) {
7866  blink = !blink;
7867  }
7868  if( action == "LIST_ITEMS" ) {
7870  } else if( action == "TOGGLE_FAST_SCROLL" ) {
7871  fast_scroll = !fast_scroll;
7872  } else if( action == "toggle_pixel_minimap" ) {
7874 
7875  if( show_window && ui ) {
7876  ui->mark_resize();
7877  }
7878  } else if( action == "LEVEL_UP" || action == "LEVEL_DOWN" ) {
7879  const int dz = action == "LEVEL_UP" ? 1 : -1;
7880  lz = clamp( lz + dz, min_levz, max_levz );
7881  center.z = clamp( center.z + dz, min_levz, max_levz );
7882 
7883  add_msg_debug( debugmode::DF_GAME, "levx: %d, levy: %d, levz: %d",
7884  get_map().get_abs_sub().x(), get_map().get_abs_sub().y(), center.z );
7885  u.view_offset.z = center.z - u.posz();
7887  // Fix player character not visible from above
7888  m.build_map_cache( u.posz() );
7890  } else if( action == "TRAVEL_TO" ) {
7891  const std::optional<std::vector<tripoint_bub_ms>> try_route = safe_route_to( u, lp,
7892  0, []( const std::string & msg ) {
7893  add_msg( msg );
7894  } );
7895  if( try_route.has_value() ) {
7896  u.set_destination( *try_route );
7897  continue;
7898  }
7899  } else if( action == "debug_scent" || action == "debug_scent_type" ) {
7901  display_scent();
7902  }
7903  } else if( action == "debug_temp" ) {
7906  }
7907  } else if( action == "debug_lighting" ) {
7909  display_lighting();
7910  }
7911  } else if( action == "debug_transparency" ) {
7914  }
7915  } else if( action == "debug_radiation" ) {
7918  }
7919  } else if( action == "debug_hour_timer" ) {
7921  } else if( action == "EXTENDED_DESCRIPTION" ) {
7922  // TODO: fix point types
7923  extended_description( lp.raw() );
7924  } else if( action == "CHANGE_MONSTER_NAME" ) {
7925  creature_tracker &creatures = get_creature_tracker();
7926  monster *const mon = creatures.creature_at<monster>( lp, true );
7927  if( mon ) {
7929  popup
7930  .title( _( "Nickname:" ) )
7931  .width( 85 )
7932  .edit( mon->nickname );
7933  }
7934  } else if( action == "CENTER" ) {
7935  center = u.pos();
7936  lp = u.pos_bub();
7937  u.view_offset.z = 0;
7938  } else if( action == "MOUSE_MOVE" || action == "TIMEOUT" ) {
7939  // This block is structured this way so that edge scroll can work
7940  // whether the mouse is moving at the edge or simply stationary
7941  // at the edge. But even if edge scroll isn't in play, there's
7942  // other things for us to do here.
7943 
7944  if( edge_scrolling ) {
7945  center += action == "MOUSE_MOVE" ? edge_scroll * 2 : edge_scroll;
7946  } else if( action == "MOUSE_MOVE" ) {
7947  const std::optional<tripoint> mouse_pos = ctxt.get_coordinates( w_terrain, ter_view_p.xy(), true );
7948  if( mouse_pos ) {
7949  lx = mouse_pos->x;
7950  ly = mouse_pos->y;
7951  }
7952  }
7953  } else if( std::optional<tripoint> vec = ctxt.get_direction( action ) ) {
7954  if( fast_scroll ) {
7955  vec->x *= soffset;
7956  vec->y *= soffset;
7957  }
7958 
7959  lx = lx + vec->x;
7960  ly = ly + vec->y;
7961  center.x = center.x + vec->x;
7962  center.y = center.y + vec->y;
7963  } else if( action == "throw_blind" ) {
7964  result.peek_action = PA_BLIND_THROW;
7965  } else if( action == "zoom_in" ) {
7966  // TODO: fix point types
7967  center.x = lp.x();
7968  center.y = lp.y();
7969  zoom_in();
7971  } else if( action == "zoom_out" ) {
7972  // TODO: fix point types
7973  center.x = lp.x();
7974  center.y = lp.y();
7975  zoom_out();
7977  }
7978  } while( action != "QUIT" && action != "CONFIRM" && action != "SELECT" && action != "TRAVEL_TO" &&
7979  action != "throw_blind" );
7980 
7981  if( center.z != old_levz ) {
7982  m.invalidate_map_cache( old_levz );
7983  m.build_map_cache( old_levz );
7984  u.view_offset.z = 0;
7985  }
7986 
7987  ctxt.reset_timeout();
7988  u.view_offset = prev_offset;
7989  zone_cb = nullptr;
7990  is_looking = false;
7991 
7993  bVMonsterLookFire = true;
7994 
7995  if( action == "CONFIRM" || action == "SELECT" ) {
7996  // TODO: fix point types
7997  result.position = is_moving_zone ? zone_start : lp.raw();
7998  }
7999 
8000 #if defined(TILES)
8001  if( is_moving_zone && get_zoom() != prev_tileset_zoom ) {
8002  // Reset the tileset zoom to the previous value
8003  set_zoom( prev_tileset_zoom );
8005  }
8006 #endif
8007 
8008  return result;
8009 }
int fov_3d_z_range
tripoint mouse_edge_scrolling_terrain(input_context &ctxt)
Used to implement mouse "edge scrolling".
Definition: game.cpp:2437
void set_zoom(int level)
Definition: game.cpp:8203
void draw_look_around_cursor(const tripoint &lp, const visibility_variables &cache)
Definition: game.cpp:6418
void extended_description(const tripoint &p)
Long description of (visible) things at tile.
void pre_print_all_tile_info(const tripoint &lp, const catacurses::window &w_info, int &line, int last_line, const visibility_variables &cache)
Definition: game.cpp:7575
int get_zoom() const
Definition: game.cpp:8215
void invalidate_map_cache(int zlev)
Definition: map.cpp:375
void invalidate_visibility_cache()
Definition: map.cpp:6874
std::string nickname
Definition: monster.h:566
int square_dist(const coords::coord_point< Point, Origin, Scale, LhsInBounds > &loc1, const coords::coord_point< Point, Origin, Scale, RhsInBounds > &loc2)
Definition: coordinates.h:755
@ D_PEDANTIC_INFO
Definition: debug.h:143
static shared_ptr_fast< game::draw_callback_t > create_zone_callback(const std::optional< tripoint > &zone_start, const std::optional< tripoint > &zone_end, const bool &zone_blink, const bool &zone_cursor, const bool &is_moving_zone=false)
Definition: game.cpp:3849
@ PA_BLIND_THROW
Definition: game.h:108
constexpr int OVERMAP_HEIGHT
constexpr int OVERMAP_DEPTH
std::optional< peek_act > peek_action
Definition: game.h:114

References _, action, add_draw_callback(), add_msg(), add_msg_debug, map::build_map_cache(), bVMonsterLookFire, c_green, c_light_green, c_red, c_white, center, center_print(), clamp(), create_zone_callback(), creature_tracker::creature_at(), D_PEDANTIC_INFO, dbg, debugmode::DF_GAME, display_lighting(), display_radiation(), display_scent(), display_temperature(), display_transparency(), draw_border(), draw_look_around_cursor(), extended_description(), fov_3d_z_range, map::get_abs_sub(), input_context::get_action_name(), input_context::get_coordinates(), get_creature_tracker, panel_manager::get_current_layout(), input_context::get_desc(), input_context::get_direction(), panel_manager::get_manager(), get_map, map::get_visibility_variables_cache(), panel_manager::get_width_left(), get_zoom(), catacurses::getmaxy(), input_context::handle_input(), invalidate_main_ui_adaptor(), map::invalidate_map_cache(), map::invalidate_visibility_cache(), is_looking, MAP_SHARING::isCompetitive(), MAP_SHARING::isDebugger(), input_context::keys_bound_to(), list_items_monsters(), m, mark_main_ui_adaptor_resize(), max(), min(), mouse_edge_scrolling_terrain(), mvwprintz(), catacurses::newwin(), monster::nickname, OVERMAP_DEPTH, OVERMAP_HEIGHT, PA_BLIND_THROW, panel_layout::panels(), look_around_result::peek_action, pixel_minimap_option, point, popup(), Creature::pos(), Creature::pos_bub(), look_around_result::position, Creature::posz(), pre_print_all_tile_info(), coords::coord_point_mut< Point, Subpoint, InBounds >::raw(), ui_manager::redraw(), reenter_fullscreen(), input_context::register_action(), input_context::register_directions(), input_context::reset_timeout(), right_print(), safe_route_to(), Character::sees(), Character::set_destination(), input_context::set_iso(), input_context::set_timeout(), set_zoom(), square_dist(), string_format(), temp_exit_fullscreen(), ter_view_p, TERMX, TERMY, tileset_zoom, toggle_debug_hour_timer(), toggle_pixel_minimap(), tripoint_zero, u, map::update_visibility_cache(), Character::view_offset, w_pixel_minimap, w_terrain, catacurses::werase(), catacurses::wnoutrefresh(), coords::coord_point_mut< Point, Subpoint, InBounds >::x(), tripoint::xy(), coords::coord_point_mut< Point, Subpoint, InBounds >::y(), coords::coord_point_mut< Point, Subpoint, InBounds >::z(), tripoint::z, zoom_in(), and zoom_out().

◆ look_around() [3/3]

look_around_result game::look_around ( look_around_params  looka_params)

Definition at line 8011 of file game.cpp.

8012 {
8013  return look_around( looka_params.show_window, looka_params.center, looka_params.start_point,
8014  looka_params.has_first_point, looka_params.select_zone, looka_params.peeking, false, tripoint_zero,
8015  looka_params.change_lv );
8016 }
const bool show_window
Definition: game.h:117
const tripoint & start_point
Definition: game.h:119
bool has_first_point
Definition: game.h:120
bool change_lv
Definition: game.h:123
tripoint & center
Definition: game.h:118
bool select_zone
Definition: game.h:121

References look_around_params::center, look_around_params::change_lv, look_around_params::has_first_point, look_around(), look_around_params::peeking, look_around_params::select_zone, look_around_params::show_window, look_around_params::start_point, and tripoint_zero.

◆ look_debug()

std::optional< tripoint > game::look_debug ( )

Definition at line 6411 of file game.cpp.

6412 {
6413  editmap edit;
6414  return edit.edit();
6415 }
std::optional< tripoint > edit()
Definition: editmap.cpp:346

References editmap::edit().

◆ mark_main_ui_adaptor_resize()

void game::mark_main_ui_adaptor_resize ( ) const

Definition at line 3806 of file game.cpp.

3807 {
3809  if( ui ) {
3810  ui->mark_resize();
3811  }
3812 }

References main_ui_adaptor.

Referenced by do_regular_action(), list_items(), list_monsters(), look_around(), toggle_fullscreen(), and toggle_pixel_minimap().

◆ memorial()

memorial_logger & game::memorial ( )
private

Definition at line 3437 of file game.cpp.

3438 {
3439  return *memorial_logger_ptr;
3440 }

References memorial_logger_ptr.

Referenced by save_player_data(), and write_memorial_file().

◆ mon_info_update()

void game::mon_info_update ( )

Definition at line 4596 of file game.cpp.

4597 {
4598  int newseen = 0;
4599  const int safe_proxy_dist = get_option<int>( "SAFEMODEPROXIMITY" );
4600  const int iProxyDist = ( safe_proxy_dist <= 0 ) ? MAX_VIEW_DISTANCE :
4601  safe_proxy_dist;
4602 
4603  monster_visible_info &mon_visible = u.get_mon_visible();
4604  auto &new_seen_mon = mon_visible.new_seen_mon;
4605  auto &unique_types = mon_visible.unique_types;
4606  auto &unique_mons = mon_visible.unique_mons;
4607  auto &dangerous = mon_visible.dangerous;
4608  mon_visible.has_dangerous_creature_in_proximity = false;
4609 
4610  // 7 0 1 unique_types uses these indices;
4611  // 6 8 2 0-7 are provide by direction_from()
4612  // 5 4 3 8 is used for local monsters (for when we explain them below)
4613  for( auto &t : unique_types ) {
4614  t.clear();
4615  }
4616  for( auto &m : unique_mons ) {
4617  m.clear();
4618  }
4619  std::fill( dangerous.begin(), dangerous.end(), false );
4620 
4621  const tripoint view = u.pos() + u.view_offset;
4622  new_seen_mon.clear();
4623 
4624  static time_point previous_turn = calendar::turn_zero;
4625  const time_duration sm_ignored_turns =
4626  time_duration::from_turns( get_option<int>( "SAFEMODEIGNORETURNS" ) );
4627 
4628  for( Creature *c : u.get_visible_creatures( MAPSIZE_X ) ) {
4629  monster *m = dynamic_cast<monster *>( c );
4630  npc *p = dynamic_cast<npc *>( c );
4631  const direction dir_to_mon = direction_from( view.xy(), point( c->posx(), c->posy() ) );
4632  const point m2( -view.xy() + point( POSX + c->posx(), POSY + c->posy() ) );
4633  int index = 8;
4634  if( !is_valid_in_w_terrain( m2 ) ) {
4635  // for compatibility with old code, see diagram below, it explains the values for index,
4636  // also might need revisiting one z-levels are in.
4637  switch( dir_to_mon ) {
4639  case direction::NORTHWEST:
4641  index = 7;
4642  break;
4643  case direction::ABOVENORTH:
4644  case direction::NORTH:
4645  case direction::BELOWNORTH:
4646  index = 0;
4647  break;
4649  case direction::NORTHEAST:
4651  index = 1;
4652  break;
4653  case direction::ABOVEWEST:
4654  case direction::WEST:
4655  case direction::BELOWWEST:
4656  index = 6;
4657  break;
4659  case direction::CENTER:
4661  index = 8;
4662  break;
4663  case direction::ABOVEEAST:
4664  case direction::EAST:
4665  case direction::BELOWEAST:
4666  index = 2;
4667  break;
4669  case direction::SOUTHWEST:
4671  index = 5;
4672  break;
4673  case direction::ABOVESOUTH:
4674  case direction::SOUTH:
4675  case direction::BELOWSOUTH:
4676  index = 4;
4677  break;
4679  case direction::SOUTHEAST:
4681  index = 3;
4682  break;
4683  case direction::last:
4684  cata_fatal( "invalid direction" );
4685  }
4686  }
4687 
4688  bool need_processing = false;
4689  const bool safemode_empty = get_safemode().empty();
4690 
4691  if( m != nullptr ) {
4692  //Safemode monster check
4693  monster &critter = *m;
4694 
4695  const monster_attitude matt = critter.attitude( &u );
4696  const int mon_dist = rl_dist( u.pos(), critter.pos() );
4697  if( !safemode_empty ) {
4698  need_processing = get_safemode().check_monster(
4699  critter.name(),
4700  critter.attitude_to( u ),
4701  mon_dist,
4703  } else {
4704  need_processing = MATT_ATTACK == matt || MATT_FOLLOW == matt;
4705  }
4706  if( need_processing ) {
4707  if( index < 8 && critter.sees( get_player_character() ) ) {
4708  dangerous[index] = true;
4709  }
4710 
4711  if( !safemode_empty || mon_dist <= iProxyDist ) {
4712  bool passmon = false;
4713  mon_visible.has_dangerous_creature_in_proximity = true;
4714  if( critter.ignoring > 0 ) {
4715  if( safe_mode != SAFE_MODE_ON ) {
4716  critter.ignoring = 0;
4717  } else if( ( sm_ignored_turns == time_duration() ||
4718  ( critter.lastseen_turn &&
4719  *critter.lastseen_turn > calendar::turn - sm_ignored_turns ) ) &&
4720  ( mon_dist > critter.ignoring / 2 || mon_dist < 6 ) ) {
4721  passmon = true;
4722  }
4723  critter.lastseen_turn = calendar::turn;
4724  }
4725 
4726  if( !passmon ) {
4727  newseen++;
4728  new_seen_mon.push_back( shared_from( critter ) );
4729  }
4730  }
4731  }
4732 
4733  std::vector<std::pair<const mtype *, int>> &vec = unique_mons[index];
4734  const auto mon_it = std::find_if( vec.begin(), vec.end(),
4735  [&]( const std::pair<const mtype *, int> &elem ) {
4736  return elem.first == critter.type;
4737  } );
4738  if( mon_it == vec.end() ) {
4739  vec.emplace_back( critter.type, 1 );
4740  } else {
4741  mon_it->second++;
4742  }
4743  } else if( p != nullptr ) {
4744  //Safe mode NPC check
4745 
4746  const int npc_dist = rl_dist( u.pos(), p->pos() );
4747  if( !safemode_empty ) {
4748  need_processing = get_safemode().check_monster(
4749  get_safemode().npc_type_name(),
4750  p->attitude_to( u ),
4751  npc_dist,
4753  } else {
4754  need_processing = npc_dist <= iProxyDist &&
4755  p->get_attitude() == NPCATT_KILL;
4756  }
4757  if( need_processing ) {
4758  mon_visible.has_dangerous_creature_in_proximity = true;
4759  newseen++;
4760  }
4761  unique_types[index].push_back( p );
4762  }
4763  }
4764 
4765  if( uistate.distraction_hostile_spotted && newseen > mostseen ) {
4766  if( newseen - mostseen == 1 ) {
4767  if( !new_seen_mon.empty() ) {
4768  monster &critter = *new_seen_mon.back();
4770  string_format( _( "%s spotted!" ), critter.name() ) );
4771  if( u.has_trait( trait_M_DEFENDER ) && critter.type->in_species( species_PLANT ) ) {
4772  add_msg( m_warning, _( "We have detected a %s - an enemy of the Mycus!" ), critter.name() );
4774  u.add_effect( effect_adrenaline_mycus, 30_minutes );
4775  } else if( u.get_effect_int( effect_adrenaline_mycus ) == 1 ) {
4776  // Triffids present. We ain't got TIME to adrenaline comedown!
4777  u.add_effect( effect_adrenaline_mycus, 15_minutes );
4778  u.mod_pain( 3 ); // Does take it out of you, though
4779  add_msg( m_info, _( "Our fibers strain with renewed wrath!" ) );
4780  }
4781  }
4782  } else {
4783  //Hostile NPC
4785  _( "Hostile survivor spotted!" ) );
4786  }
4787  } else {
4789  }
4790  turnssincelastmon = 0_turns;
4791  if( safe_mode == SAFE_MODE_ON ) {
4793  }
4794  } else if( calendar::turn > previous_turn && get_option<bool>( "AUTOSAFEMODE" ) &&
4795  newseen == 0 ) { // Auto safe mode, but only if it's a new turn
4796  turnssincelastmon += calendar::turn - previous_turn;
4797  time_duration auto_safe_mode =
4798  time_duration::from_turns( get_option<int>( "AUTOSAFEMODETURNS" ) );
4799  if( turnssincelastmon >= auto_safe_mode && safe_mode == SAFE_MODE_OFF ) {
4801  add_msg( m_info, _( "Safe mode ON!" ) );
4802  }
4803  }
4804 
4805  if( newseen == 0 && safe_mode == SAFE_MODE_STOP ) {
4807  }
4808 
4809  previous_turn = calendar::turn;
4810  mostseen = newseen;
4811 }
int get_effect_int(const efftype_id &eff_id, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns the intensity of the matching effect.
Definition: creature.cpp:1872
bool cancel_activity_or_ignore_query(distraction_type type, const std::string &text)
Asks if the player wants to cancel their activity and if so cancels it.
Definition: game.cpp:1455
monster_attitude attitude(const Character *u=nullptr) const
Definition: monster.cpp:1496
std::optional< time_point > lastseen_turn
Definition: monster.h:574
Attitude attitude_to(const Creature &other) const override
Attitude (of this creature) towards another creature.
Definition: npc.cpp:2386
rule_state check_monster(const std::string &creature_name_in, Creature::Attitude attitude_in, int proximity_in, bool driving=false) const
bool empty() const
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:221
A point in the game time.
Definition: calendar.h:460
bool distraction_hostile_spotted
Definition: uistate.h:149
#define cata_fatal(...)
Definition: debug.h:83
static const species_id species_PLANT("PLANT")
static const trait_id trait_M_DEFENDER("M_DEFENDER")
static const efftype_id effect_adrenaline_mycus("adrenaline_mycus")
monster_attitude
Definition: monster.h:57
@ MATT_FOLLOW
Definition: monster.h:63
@ MATT_ATTACK
Definition: monster.h:64
@ NPCATT_KILL
Definition: npc.h:117
bool has_dangerous_creature_in_proximity
Definition: avatar.h:78
std::array< std::vector< npc * >, 9 > unique_types
Definition: avatar.h:70
std::array< bool, 8 > dangerous
Definition: avatar.h:74
std::array< std::vector< std::pair< const mtype *, int > >, 9 > unique_mons
Definition: avatar.h:71
bool in_species(const species_id &spec) const
Definition: mtype.cpp:385

References _, ABOVECENTER, ABOVEEAST, ABOVENORTH, ABOVENORTHEAST, ABOVENORTHWEST, ABOVESOUTH, ABOVESOUTHEAST, ABOVESOUTHWEST, ABOVEWEST, Creature::add_effect(), add_msg(), monster::attitude(), monster::attitude_to(), npc::attitude_to(), BELOWCENTER, BELOWEAST, BELOWNORTH, BELOWNORTHEAST, BELOWNORTHWEST, BELOWSOUTH, BELOWSOUTHEAST, BELOWSOUTHWEST, BELOWWEST, BLACKLISTED, c, cancel_activity_or_ignore_query(), cata_fatal, CENTER, safemode::check_monster(), Character::controlling_vehicle, monster_visible_info::dangerous, direction_from(), uistatedata::distraction_hostile_spotted, EAST, effect_adrenaline_mycus, safemode::empty(), time_duration::from_turns(), npc::get_attitude(), Creature::get_effect_int(), avatar::get_mon_visible(), get_player_character, get_safemode(), Character::get_visible_creatures(), monster_visible_info::has_dangerous_creature_in_proximity, Creature::has_effect(), Character::has_trait(), hostile_spotted_far, monster::ignoring, mtype::in_species(), is_valid_in_w_terrain(), last, monster::lastseen_turn, m, m_info, m_warning, MAPSIZE_X, MATT_ATTACK, MATT_FOLLOW, MAX_VIEW_DISTANCE, Character::mod_pain(), mostseen, monster::name(), monster_visible_info::new_seen_mon, NORTH, NORTHEAST, NORTHWEST, NPCATT_KILL, Creature::pos(), POSX, POSY, rl_dist(), safe_mode, SAFE_MODE_OFF, SAFE_MODE_ON, SAFE_MODE_STOP, Creature::sees(), set_safe_mode(), shared_from(), SOUTH, SOUTHEAST, SOUTHWEST, species_PLANT, string_format(), trait_M_DEFENDER, calendar::turn, calendar::turn_zero, turnssincelastmon, monster::type, u, uistate, monster_visible_info::unique_mons, monster_visible_info::unique_types, Character::view_offset, WEST, and tripoint::xy().

◆ mouse_edge_scrolling()

std::pair< tripoint, tripoint > game::mouse_edge_scrolling ( input_context ctxt,
int  speed,
const tripoint last,
bool  iso 
)
private

Definition at line 2384 of file game.cpp.

2386 {
2387  const int rate = get_option<int>( "EDGE_SCROLL" );
2388  auto ret = std::make_pair( tripoint_zero, last );
2389  if( rate == -1 ) {
2390  // Fast return when the option is disabled.
2391  return ret;
2392  }
2393  // Ensure the parameters are used even if the #if below is false
2394  ( void ) ctxt;
2395  ( void ) speed;
2396  ( void ) iso;
2397 #if (defined TILES || defined _WIN32 || defined WINDOWS)
2398  std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
2399  if( now < last_mouse_edge_scroll + std::chrono::milliseconds( rate ) ) {
2400  return ret;
2401  } else {
2402  last_mouse_edge_scroll = now;
2403  }
2404  const input_event event = ctxt.get_raw_input();
2405  if( event.type == input_event_t::mouse ) {
2406  const point threshold( projected_window_width() / 100, projected_window_height() / 100 );
2407  if( event.mouse_pos.x <= threshold.x ) {
2408  ret.first.x -= speed;
2409  if( iso ) {
2410  ret.first.y -= speed;
2411  }
2412  } else if( event.mouse_pos.x >= projected_window_width() - threshold.x ) {
2413  ret.first.x += speed;
2414  if( iso ) {
2415  ret.first.y += speed;
2416  }
2417  }
2418  if( event.mouse_pos.y <= threshold.y ) {
2419  ret.first.y -= speed;
2420  if( iso ) {
2421  ret.first.x += speed;
2422  }
2423  } else if( event.mouse_pos.y >= projected_window_height() - threshold.y ) {
2424  ret.first.y += speed;
2425  if( iso ) {
2426  ret.first.x -= speed;
2427  }
2428  }
2429  ret.second = ret.first;
2430  } else if( event.type == input_event_t::timeout ) {
2431  ret.first = ret.second;
2432  }
2433 #endif
2434  return ret;
2435 }

References input_context::get_raw_input(), iso, last, last_mouse_edge_scroll, mouse, cata::hash64_detail::ret, speed, timeout, tripoint_zero, point::x, and point::y.

Referenced by mouse_edge_scrolling_overmap(), and mouse_edge_scrolling_terrain().

◆ mouse_edge_scrolling_overmap()

tripoint game::mouse_edge_scrolling_overmap ( input_context ctxt)

This variant is suitable for the overmap.

Definition at line 2446 of file game.cpp.

2447 {
2448  // overmap has no iso mode
2452  return ret.first;
2453 }
std::pair< tripoint, tripoint > mouse_edge_scrolling(input_context &ctxt, int speed, const tripoint &last, bool iso)
Definition: game.cpp:2384
tripoint last_mouse_edge_scroll_vector_terrain
Definition: game.h:1207
tripoint last_mouse_edge_scroll_vector_overmap
Definition: game.h:1208

References last_mouse_edge_scroll_vector_overmap, last_mouse_edge_scroll_vector_terrain, mouse_edge_scrolling(), cata::hash64_detail::ret, and tripoint_zero.

◆ mouse_edge_scrolling_terrain()

tripoint game::mouse_edge_scrolling_terrain ( input_context ctxt)

Used to implement mouse "edge scrolling".

Returns a tripoint which is a vector of the resulting "move", i.e. (0, 0, 0) if the mouse is not at the edge of the screen, otherwise some (x, y, 0) depending on which edges are hit. This variant adjust scrolling speed according to zoom level, making it suitable when viewing the "terrain".

Definition at line 2437 of file game.cpp.

2438 {
2440  last_mouse_edge_scroll_vector_terrain, g->is_tileset_isometric() );
2443  return ret.first;
2444 }

References DEFAULT_TILESET_ZOOM, g, last_mouse_edge_scroll_vector_overmap, last_mouse_edge_scroll_vector_terrain, max(), mouse_edge_scrolling(), cata::hash64_detail::ret, tileset_zoom, and tripoint_zero.

Referenced by look_around().

◆ move_save_to_graveyard()

void game::move_save_to_graveyard ( )
private

Definition at line 3005 of file game.cpp.

3006 {
3007  const std::string &save_dir = PATH_INFO::world_base_save_path();
3008  const std::string graveyard_dir = PATH_INFO::graveyarddir() + "/" + timestamp_now() + "/";
3009  const std::string &prefix = base64_encode( u.get_save_id() ) + ".";
3010 
3011  if( !assure_dir_exist( graveyard_dir ) ) {
3012  debugmsg( "could not create graveyard path '%s'", graveyard_dir );
3013  }
3014 
3015  const auto save_files = get_files_from_path( prefix, save_dir );
3016  if( save_files.empty() ) {
3017  debugmsg( "could not find save files in '%s'", save_dir );
3018  }
3019 
3020  for( const auto &src_path : save_files ) {
3021  const std::string dst_path = graveyard_dir +
3022  src_path.substr( src_path.rfind( '/' ), std::string::npos );
3023 
3024  if( rename_file( src_path, dst_path ) ) {
3025  continue;
3026  }
3027 
3028  debugmsg( "could not rename file '%s' to '%s'", src_path, dst_path );
3029 
3030  if( remove_file( src_path ) ) {
3031  continue;
3032  }
3033 
3034  debugmsg( "could not remove file '%s'", src_path );
3035  }
3036 }
std::string base64_encode(const std::string &str)
std::string get_save_id() const
Definition: avatar.h:128
bool remove_file(const std::string &path)
Definition: filesystem.cpp:147
bool assure_dir_exist(const std::string &path)
Definition: filesystem.cpp:68
bool rename_file(const std::string &old_path, const std::string &new_path)
Definition: filesystem.cpp:159
std::vector< std::string > get_files_from_path(const std::string &pattern, const std::string &root_path, const bool recursive_search, const bool match_extension)
Returns a vector of files or directories matching pattern at root_path.
Definition: filesystem.cpp:419
static std::string timestamp_now()
Definition: game.cpp:2997
std::string graveyarddir()
Definition: path_info.cpp:302
std::string world_base_save_path()
Definition: game.cpp:13258

References assure_dir_exist(), base64_encode(), debugmsg, get_files_from_path(), avatar::get_save_id(), PATH_INFO::graveyarddir(), prefix, remove_file(), rename_file(), timestamp_now(), u, and PATH_INFO::world_base_save_path().

◆ moving_vehicle_dismount()

void game::moving_vehicle_dismount ( const tripoint dest_loc)

Handles players exiting from moving vehicles.

Definition at line 5811 of file game.cpp.

5812 {
5813  const optional_vpart_position vp = m.veh_at( u.pos() );
5814  if( !vp ) {
5815  debugmsg( "Tried to exit non-existent vehicle." );
5816  return;
5817  }
5818  vehicle *const veh = &vp->vehicle();
5819  if( u.pos() == dest_loc ) {
5820  debugmsg( "Need somewhere to dismount towards." );
5821  return;
5822  }
5823  tileray ray( dest_loc.xy() + point( -u.posx(), -u.posy() ) );
5824  // TODO:: make dir() const correct!
5825  const units::angle d = ray.dir();
5826  add_msg( _( "You dive from the %s." ), veh->name );
5827  m.unboard_vehicle( u.pos() );
5828  u.mod_moves( -to_moves<int>( 2_seconds ) );
5829  // Dive three tiles in the direction of tox and toy
5830  fling_creature( &u, d, 30, true, true );
5831  // Hit the ground according to vehicle speed
5833  if( veh->velocity > 0 ) {
5834  fling_creature( &u, veh->face.dir(), veh->velocity / static_cast<float>( 100 ), false, true );
5835  } else {
5836  fling_creature( &u, veh->face.dir() + 180_degrees,
5837  -( veh->velocity ) / static_cast<float>( 100 ), false, true );
5838  }
5839  }
5840 }
bool fling_creature(Creature *c, const units::angle &dir, float flvel, bool controlled=false, bool intentional=false)
Flings the input creature in the given direction.
Definition: game.cpp:11735

References _, add_msg(), debugmsg, tileray::dir(), vehicle::face, fling_creature(), map::has_flag(), m, Creature::mod_moves(), vehicle::name, Creature::pos(), Creature::posx(), Creature::posy(), TFLAG_SWIMMABLE, u, map::unboard_vehicle(), map::veh_at(), vehicle::velocity, and tripoint::xy().

◆ natural_light_level()

float game::natural_light_level ( int  zlev) const

Definition at line 4396 of file game.cpp.

4397 {
4398  // ignore while underground or above limits
4399  if( zlev > OVERMAP_HEIGHT || zlev < 0 ) {
4400  return LIGHT_AMBIENT_MINIMAL;
4401  }
4402 
4404  // Already found the light level for now?
4405  return latest_lightlevels[zlev];
4406  }
4407 
4408  float ret = LIGHT_AMBIENT_MINIMAL;
4409 
4410  // Sunlight/moonlight related stuff
4413 
4414  // Artifact light level changes here. Even though some of these only have an effect
4415  // aboveground it is cheaper performance wise to simply iterate through the entire
4416  // list once instead of twice.
4417  float mod_ret = -1;
4418  // Each artifact change does std::max(mod_ret, new val) since a brighter end value
4419  // will trump a lower one.
4420  if( const timed_event *e = timed_events.get( timed_event_type::DIM ) ) {
4421  // timed_event_type::DIM slowly dims the natural sky level, then relights it.
4422  const time_duration left = e->when - calendar::turn;
4423  // timed_event_type::DIM has an occurrence date of turn + 50, so the first 25 dim it,
4424  if( left > 25_turns ) {
4425  mod_ret = std::max( static_cast<double>( mod_ret ), ( ret * ( left - 25_turns ) ) / 25_turns );
4426  // and the last 25 scale back towards normal.
4427  } else {
4428  mod_ret = std::max( static_cast<double>( mod_ret ), ( ret * ( 25_turns - left ) ) / 25_turns );
4429  }
4430  }
4432  // timed_event_type::ARTIFACT_LIGHT causes everywhere to become as bright as day.
4433  mod_ret = std::max<float>( ret, default_daylight_level() );
4434  }
4436  mod_ret = e->strength;
4437  }
4438  // If we had a changed light level due to an artifact event then it overwrites
4439  // the natural light level.
4440  if( mod_ret > -1 ) {
4441  ret = mod_ret;
4442  }
4443 
4444  // Cap everything to our minimum light level
4445  ret = std::max<float>( LIGHT_AMBIENT_MINIMAL, ret );
4446 
4447  latest_lightlevels[zlev] = ret;
4448 
4449  return ret;
4450 }
float default_daylight_level()
How much light is provided in full daylight.
Definition: calendar.cpp:47
float sun_moon_light_at(const time_point &p)
Returns the current sunlight plus moonlight level.
Definition: calendar.cpp:416
std::array< float, OVERMAP_LAYERS > latest_lightlevels
Definition: game.h:1177
bool queued(timed_event_type type) const
timed_event * get(timed_event_type type)
constexpr float LIGHT_AMBIENT_MINIMAL
Definition: lightmap.h:12
int light_modifier
Definition: weather_type.h:93

References ARTIFACT_LIGHT, CUSTOM_LIGHT_LEVEL, default_daylight_level(), DIM, timed_event_manager::get(), get_weather, latest_lightlevels, left, LIGHT_AMBIENT_MINIMAL, weather_type::light_modifier, max(), OVERMAP_HEIGHT, timed_event_manager::queued(), cata::hash64_detail::ret, sun_moon_light_at(), timed_events, calendar::turn, and weather_manager::weather_id.

Referenced by light_level().

◆ npc_menu()

bool game::npc_menu ( npc who)

Returns true if the menu handled stuff and player shouldn't do anything else.

Perception slightly increases precision when examining NPCs' wounds \EFFECT_FIRSTAID increases precision when examining NPCs' wounds

Definition at line 5941 of file game.cpp.

5942 {
5943  enum choices : int {
5944  talk = 0,
5945  swap_pos,
5946  push,
5947  examine_wounds,
5948  examine_status,
5949  use_item,
5950  sort_armor,
5951  attack,
5952  disarm,
5953  steal,
5954  trade
5955  };
5956 
5957  const bool obeys = debug_mode || ( who.is_friendly( u ) && !who.in_sleep_state() );
5958 
5959  uilist amenu;
5960 
5961  amenu.text = string_format( _( "What to do with %s?" ), who.disp_name() );
5962  amenu.addentry( talk, true, 't', _( "Talk" ) );
5963  amenu.addentry( swap_pos, obeys && !who.is_mounted() &&
5964  !u.is_mounted(), 's', _( "Swap positions" ) );
5965  amenu.addentry( push, obeys && !who.is_mounted(), 'p', _( "Push away" ) );
5966  amenu.addentry( examine_wounds, true, 'w', _( "Examine wounds" ) );
5967  amenu.addentry( examine_status, true, 'e', _( "Examine status" ) );
5968  amenu.addentry( use_item, true, 'i', _( "Use item on" ) );
5969  amenu.addentry( sort_armor, true, 'r', _( "Sort armor" ) );
5970  amenu.addentry( attack, true, 'a', _( "Attack" ) );
5971  if( !who.is_player_ally() ) {
5972  amenu.addentry( disarm, who.is_armed(), 'd', _( "Disarm" ) );
5973  amenu.addentry( steal, !who.is_enemy(), 'S', _( "Steal" ) );
5974  } else {
5975  amenu.addentry( trade, true, 'b', _( "Trade" ) );
5976  }
5977 
5978  amenu.query();
5979 
5980  const int choice = amenu.ret;
5981  if( choice == talk ) {
5982  u.talk_to( get_talker_for( who ) );
5983  } else if( choice == swap_pos ) {
5984  if( !prompt_dangerous_tile( who.pos() ) ) {
5985  return true;
5986  }
5987  if( u.get_grab_type() == object_type::NONE ) {
5988  // TODO: Make NPCs protest when displaced onto dangerous crap
5989  add_msg( _( "You swap places with %s." ), who.get_name() );
5990  swap_critters( u, who );
5991  // TODO: Make that depend on stuff
5992  u.mod_moves( -200 );
5993  } else {
5994  add_msg( _( "You cannot swap places while grabbing something." ) );
5995  }
5996  } else if( choice == push ) {
5997  // TODO: Make NPCs protest when displaced onto dangerous crap
5998  tripoint oldpos = who.pos();
5999  who.move_away_from( u.pos(), true );
6000  u.mod_moves( -20 );
6001  if( oldpos != who.pos() ) {
6002  add_msg( _( "%s moves out of the way." ), who.get_name() );
6003  } else {
6004  add_msg( m_warning, _( "%s has nowhere to go!" ), who.get_name() );
6005  }
6006  } else if( choice == examine_wounds ) {
6007  ///\EFFECT_PER slightly increases precision when examining NPCs' wounds
6008  ///\EFFECT_FIRSTAID increases precision when examining NPCs' wounds
6009  float prof_bonus = u.get_skill_level( skill_firstaid );
6010  prof_bonus = u.has_proficiency( proficiency_prof_wound_care ) ? prof_bonus + 1 : prof_bonus;
6011  prof_bonus = u.has_proficiency( proficiency_prof_wound_care_expert ) ? prof_bonus + 2 : prof_bonus;
6012  const bool precise = prof_bonus * 4 + u.per_cur >= 20;
6013  who.body_window( _( "Limbs of: " ) + who.disp_name(), true, precise, 0, 0, 0, 0.0f, 0.0f, 0.0f,
6014  0.0f, 0.0f );
6015  } else if( choice == examine_status ) {
6016  if( debug_mode || ( who.is_npc() && ( who.as_npc()->op_of_u.trust >= 5 ||
6017  who.is_friendly( u ) ) ) ||
6018  who.in_sleep_state() ) {
6019  display_bodygraph( who );
6020  } else {
6021  who.say( SNIPPET.random_from_category( "<no>" ).value_or( translation() ).translated() );
6022  }
6023  } else if( choice == use_item ) {
6024  static const std::string heal_string( "heal" );
6025  const auto will_accept = [&who]( const item & it ) {
6026  if( it.has_flag( json_flag_SPLINT ) && who.can_wear( it ).success() ) {
6027  return true;
6028  }
6029  const use_function *use_fun = it.get_use( heal_string );
6030  if( use_fun == nullptr ) {
6031  return false;
6032  }
6033 
6034  const auto *actor = dynamic_cast<const heal_actor *>( use_fun->get_actor_ptr() );
6035 
6036  return actor != nullptr &&
6037  actor->limb_power >= 0 &&
6038  actor->head_power >= 0 &&
6039  actor->torso_power >= 0;
6040  };
6041  item_location loc = game_menus::inv::titled_filter_menu( will_accept, u, _( "Use which item?" ) );
6042 
6043  if( !loc ) {
6044  add_msg( _( "Never mind" ) );
6045  return false;
6046  }
6047  item &used = *loc;
6048  if( used.has_flag( json_flag_SPLINT ) ) {
6049  std::string reason = _( "Nope." );
6050  if( who.wear_if_wanted( used, reason ) ) {
6051  u.i_rem( &used );
6052  }
6053  } else {
6054  bool did_use = u.invoke_item( &used, heal_string, who.pos() );
6055  if( did_use ) {
6056  // Note: exiting a body part selection menu counts as use here
6057  u.mod_moves( -300 );
6058  }
6059  }
6060  } else if( choice == sort_armor ) {
6061  if( who.is_hallucination() ) {
6062  who.say( SNIPPET.random_from_category( "<no>" ).value_or( translation() ).translated() );
6063  } else {
6064  who.worn.sort_armor( who );
6065  u.mod_moves( -100 );
6066  }
6067  } else if( choice == attack ) {
6068  if( who.is_enemy() || query_yn( _( "You may be attacked! Proceed?" ) ) ) {
6069  u.melee_attack( who, true );
6070  who.on_attacked( u );
6071  }
6072  } else if( choice == disarm ) {
6073  if( who.is_enemy() || query_yn( _( "You may be attacked! Proceed?" ) ) ) {
6074  u.disarm( who );
6075  }
6076  } else if( choice == steal && query_yn( _( "You may be attacked! Proceed?" ) ) ) {
6077  u.steal( who );
6078  } else if( choice == trade ) {
6079  if( who.is_hallucination() ) {
6080  who.say( SNIPPET.random_from_category( "<hallu_dont_trade>" ).value_or(
6081  translation() ).translated() );
6082  } else {
6083  npc_trading::trade( who, 0, _( "Trade" ) );
6084  }
6085  }
6086 
6087  return true;
6088 }
bool melee_attack(Creature &t, bool allow_special, const matec_id &force_technique, bool allow_unarmed=true, int forced_movecost=-1)
Sets up a melee attack and handles melee attack function calls.
Definition: melee.cpp:563
bodypart_id body_window(const std::string &menu_header, bool show_all, bool precise, int normal_bonus, int head_bonus, int torso_bonus, int bleed, float bite, float infect, float bandage_power, float disinfectant_power) const
Displays menu with body part hp, optionally with hp estimation after healing.
item i_rem(const item *it)
Remove a specific item from player possession.
bool in_sleep_state() const override
Definition: character.cpp:9307
ret_val< void > can_wear(const item &it, bool with_equip_change=false) const
Check character capable of wearing an item.
bool is_armed() const
Returns true if the character is wielding something.
Definition: melee.cpp:192
int per_cur
Definition: character.h:580
void disarm(npc &target)
Try to disarm the NPC.
Definition: melee.cpp:2845
void steal(npc &target)
Try to steal an item from the NPC's inventory.
Definition: melee.cpp:2929
bool prompt_dangerous_tile(const tripoint &dest_loc) const
Definition: game.cpp:10413
bool swap_critters(Creature &, Creature &)
Swaps positions of two creatures.
Definition: game.cpp:5435
float limb_power
How much hp to restore when healing limbs?
Definition: iuse_actor.h:867
void say(const char *const line, Args &&... args) const
Definition: npc.h:1025
npc * as_npc() override
Definition: npc.h:808
bool wear_if_wanted(const item &it, std::string &reason)
Definition: npc.cpp:1233
bool is_friendly(const Character &p) const
Definition: npc.cpp:2302
void on_attacked(const Creature &attacker)
Definition: npc.cpp:1650
void move_away_from(const tripoint &p, bool no_bash_atk=false, std::set< tripoint > *nomove=nullptr)
Definition: npcmove.cpp:3222
bool is_npc() const override
Definition: npc.h:805
npc_opinion op_of_u
Definition: npc.h:1403
std::optional< translation > random_from_category(const std::string &cat) const
Returns a random snippet out of the given category.
static const flag_id json_flag_SPLINT("SPLINT")
static const proficiency_id proficiency_prof_wound_care("prof_wound_care")
static const skill_id skill_firstaid("firstaid")
static const proficiency_id proficiency_prof_wound_care_expert("prof_wound_care_expert")
static void swap_pos(Creature &caster, const tripoint &target)
item_location steal(avatar &you, Character &victim)
Menu for stealing stuff.
item_location titled_filter_menu(const item_filter &filter, Character &you, const std::string &title, int radius=-1, const std::string &none_message="")
bool trade(npc &p, int cost, const std::string &deal)
Definition: npctrade.cpp:278
void attack(const spell &sp, Creature &caster, const tripoint &epicenter)
int trust
Definition: npc.h:233
snippet_library SNIPPET

References _, add_msg(), uilist::addentry(), npc::as_npc(), spell_effect::attack(), Character::body_window(), Character::can_wear(), debug_mode, avatar::disarm(), Character::disp_name(), display_bodygraph(), use_function::get_actor_ptr(), avatar::get_grab_type(), Character::get_name(), Character::get_skill_level(), get_talker_for(), item::has_flag(), Character::has_proficiency(), Character::i_rem(), Character::in_sleep_state(), avatar::invoke_item(), Character::is_armed(), npc::is_enemy(), npc::is_friendly(), npc::is_hallucination(), Character::is_mounted(), npc::is_npc(), npc::is_player_ally(), json_flag_SPLINT, heal_actor::limb_power, m_warning, Character::melee_attack(), Creature::mod_moves(), npc::move_away_from(), NONE, npc::on_attacked(), npc::op_of_u, Character::per_cur, Creature::pos(), proficiency_prof_wound_care, proficiency_prof_wound_care_expert, prompt_dangerous_tile(), anonymous_namespace{monexamine.cpp}::push(), uilist::query(), query_yn(), snippet_library::random_from_category(), uilist::ret, npc::say(), skill_firstaid, SNIPPET, outfit::sort_armor(), game_menus::inv::steal(), avatar::steal(), string_format(), ret_val_common::success(), swap_critters(), swap_pos(), avatar::talk_to(), uilist::text, game_menus::inv::titled_filter_menu(), npc_trading::trade(), npc_opinion::trust, u, avatar_action::use_item(), npc::wear_if_wanted(), and Character::worn.

Referenced by examine().

◆ num_creatures()

size_t game::num_creatures ( ) const

Returns the approximate number of creatures in the reality bubble.

Because of performance restrictions it may return a slightly incorrect values (as it includes dead, but not yet cleaned up creatures).

Definition at line 5273 of file game.cpp.

5274 {
5275  // Plus one for the player.
5276  return critter_tracker->size() + critter_tracker->active_npc.size() + 1;
5277 }

References critter_tracker.

Referenced by display_visibility().

◆ on_move_effects()

void game::on_move_effects ( )

Definition at line 11654 of file game.cpp.

11655 {
11656  // TODO: Move this to a character method
11657  if( !u.is_mounted() ) {
11658  const item muscle( "muscle" );
11659  for( const bionic_id &bid : u.get_bionic_fueled_with_muscle() ) {
11660  if( u.has_active_bionic( bid ) ) {// active power gen
11661  u.mod_power_level( muscle.fuel_energy() * bid->fuel_efficiency );
11662  } else {// passive power gen
11663  u.mod_power_level( muscle.fuel_energy() * bid->passive_fuel_efficiency );
11664  }
11665  }
11667  if( u.is_running() ) {
11669  } else {
11671  }
11672 
11673  // If there's not enough power to run Joint Servo, forcefully turn it off
11674  if( u.get_power_level() <= 0_mJ ) {
11676  u.add_msg_if_player( m_bad, _( "Your Joint Servo bionic powers down." ) );
11677  }
11678  }
11679  }
11680 
11681  if( u.is_running() ) {
11682  if( !u.can_run() ) {
11683  u.toggle_run_mode();
11684  }
11685  if( u.get_stamina() <= 0 ) {
11686  u.add_effect( effect_winded, 10_turns );
11687  }
11688  }
11689 
11690  // apply martial art move bonuses
11691  u.martial_arts_data->ma_onmove_effects( u );
11692 
11693  sfx::do_ambient();
11694 }
int get_stamina() const
Definition: character.cpp:6806
void mod_power_level(const units::energy &npower)
Definition: character.cpp:2852
std::vector< bionic_id > get_bionic_fueled_with_muscle() const
Return bionic_id of bionics able to use it as fuel.
Definition: bionics.cpp:3273
void force_bionic_deactivation(bionic &bio)
Definition: bionics.cpp:3507
bool is_running() const
Definition: character.cpp:2169
std::optional< bionic * > find_bionic_by_type(const bionic_id &b) const
Finds the first bionic instance that matches the bionic_id.
Definition: bionics.cpp:2800
units::energy get_power_level() const
Definition: character.cpp:2824
bool can_run() const
source of truth of whether a Character can run
Definition: character.cpp:2154
static const efftype_id effect_winded("winded")
static const bionic_id bio_jointservo("bio_jointservo")
void do_ambient()
Definition: sounds.cpp:2016
units::energy power_trigger
Power cost when the bionic's special effect is triggered.
Definition: bionics.h:43

References _, Creature::add_effect(), Character::add_msg_if_player(), bio_jointservo, Character::can_run(), sfx::do_ambient(), effect_winded, Character::find_bionic_by_type(), Character::force_bionic_deactivation(), item::fuel_energy(), Character::get_bionic_fueled_with_muscle(), Character::get_power_level(), Character::get_stamina(), Character::has_active_bionic(), Character::is_mounted(), Character::is_running(), m_bad, Character::martial_arts_data, Character::mod_power_level(), bionic_data::power_trigger, avatar::toggle_run_mode(), and u.

Referenced by phasing_move(), and walk_move().

◆ on_options_changed()

void game::on_options_changed ( )

Should be invoked whenever options change.

Definition at line 11696 of file game.cpp.

11697 {
11698 #if defined(TILES)
11699  tilecontext->on_options_changed();
11700 #endif
11701 }

◆ open_consume_item_menu()

void game::open_consume_item_menu ( )
private

Definition at line 1842 of file handle_action.cpp.

1843 {
1844  uilist as_m;
1845 
1846  as_m.text = _( "What do you want to consume?" );
1847 
1848  as_m.entries.emplace_back( 0, true, 'f', _( "Food" ) );
1849  as_m.entries.emplace_back( 1, true, 'd', _( "Drink" ) );
1850  as_m.entries.emplace_back( 2, true, 'm', _( "Medication" ) );
1851  as_m.query();
1852 
1853  avatar &player_character = get_avatar();
1854  switch( as_m.ret ) {
1855  case 0: {
1856  item_location loc = game_menus::inv::consume_food( player_character );
1857  avatar_action::eat( player_character, loc );
1858  break;
1859  }
1860  case 1: {
1861  item_location loc = game_menus::inv::consume_drink( player_character );
1862  avatar_action::eat( player_character, loc );
1863  break;
1864  }
1865  case 2:
1866  avatar_action::eat_or_use( player_character, game_menus::inv::consume_meds( player_character ) );
1867  break;
1868  default:
1869  break;
1870  }
1871 }
item_location consume_food(avatar &you)
Consuming a food item via a custom menu.
item_location consume_drink(avatar &you)
Consuming a drink item via a custom menu.
item_location consume_meds(avatar &you)
Consuming a medication item via a custom menu.

References _, game_menus::inv::consume_drink(), game_menus::inv::consume_food(), game_menus::inv::consume_meds(), avatar_action::eat(), avatar_action::eat_or_use(), uilist::entries, get_avatar, uilist::query(), uilist::ret, and uilist::text.

Referenced by do_regular_action().

◆ open_gate() [1/2]

void game::open_gate ( const tripoint p)

Definition at line 5801 of file game.cpp.

5802 {
5803  open_gate( tripoint_bub_ms( p ) );
5804 }
void open_gate(const tripoint &p)
Definition: game.cpp:5801

◆ open_gate() [2/2]

void game::open_gate ( const tripoint_bub_ms p)

Definition at line 5806 of file game.cpp.

5807 {
5808  gates::open_gate( p, u );
5809 }
void open_gate(const tripoint_bub_ms &pos, Character &p)
opens the gate via player's activity
Definition: gates.cpp:236

References gates::open_gate(), and u.

◆ peek() [1/2]

void game::peek ( )

Definition at line 6352 of file game.cpp.

6353 {
6354  const std::optional<tripoint> p = choose_direction( _( "Peek where?" ), true );
6355  if( !p ) {
6356  return;
6357  }
6358  tripoint new_pos = u.pos() + *p;
6359  if( p->z != 0 ) {
6360  // Character might peek to a different submap; ensures return location is accurate.
6361  const tripoint_abs_ms old_loc = u.get_location();
6362  vertical_move( p->z, false, true );
6363 
6364  if( old_loc != u.get_location() ) {
6365  new_pos = u.pos();
6366  u.move_to( old_loc );
6367  m.vertical_shift( old_loc.z() );
6368  } else {
6369  return;
6370  }
6371  }
6372 
6373  if( m.impassable( new_pos ) ) {
6374  return;
6375  }
6376 
6377  peek( new_pos );
6378 }
std::optional< tripoint > choose_direction(const std::string &message, const bool allow_vertical)
Request player input of a direction, possibly including vertical component.
Definition: action.cpp:1099
void move_to(const tripoint_abs_ms &loc)
Moves the creature to the given location and calls the on_move() handler.
Definition: creature.cpp:195
void vertical_shift(int newz)
Moves the map vertically to (not by!) newz.
Definition: map.cpp:8117

References _, choose_direction(), Creature::get_location(), map::impassable(), m, Creature::move_to(), Creature::pos(), u, vertical_move(), map::vertical_shift(), and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

Referenced by do_regular_action().

◆ peek() [2/2]

void game::peek ( const tripoint p)

Definition at line 6380 of file game.cpp.

6381 {
6382  u.mod_moves( -u.get_speed() * 2 );
6383  tripoint prev = u.pos();
6384  u.setpos( p );
6385  const bool is_same_pos = u.pos() == prev;
6386  const bool is_standup_peek = is_same_pos && u.is_crouching();
6387  tripoint center = p;
6388  m.build_map_cache( p.z );
6390 
6391  look_around_result result;
6392  const look_around_params looka_params = { true, center, center, false, false, true, true };
6393  if( is_standup_peek ) { // Non moving peek from crouch is a standup peek
6394  u.reset_move_mode();
6395  result = look_around( looka_params );
6397  } else { // Else is normal peek
6398  result = look_around( looka_params );
6399  u.setpos( prev );
6400  }
6401 
6402  if( result.peek_action && *result.peek_action == PA_BLIND_THROW ) {
6403  item_location loc;
6404  avatar_action::plthrow( u, loc, p );
6405  }
6406  m.invalidate_map_cache( p.z );
6408 }
bool is_crouching() const
Definition: character.cpp:2179
void activate_crouch_mode()
Definition: avatar.cpp:1351

References avatar::activate_crouch_mode(), map::build_map_cache(), center, Character::get_speed(), map::invalidate_map_cache(), map::invalidate_visibility_cache(), Character::is_crouching(), look_around(), m, Creature::mod_moves(), PA_BLIND_THROW, look_around_result::peek_action, avatar_action::plthrow(), Creature::pos(), avatar::reset_move_mode(), Creature::setpos(), u, map::update_visibility_cache(), and tripoint::z.

◆ perhaps_add_random_npc()

void game::perhaps_add_random_npc ( bool  ignore_spawn_timers_and_rates)

Definition at line 12795 of file game.cpp.

12796 {
12797  if( !ignore_spawn_timers_and_rates && !calendar::once_every( 1_hours ) ) {
12798  return;
12799  }
12800  // Create a new NPC?
12801 
12802  double spawn_time = get_option<float>( "NPC_SPAWNTIME" );
12803  if( !ignore_spawn_timers_and_rates && spawn_time == 0.0 ) {
12804  return;
12805  }
12806 
12807  // spawn algorithm is a chance per hour, but the config is specified in average days
12808  // actual chance per hour is (100 / 24 ) / days
12809  static constexpr double days_to_rate_factor = 100.0 / 24;
12810  double spawn_rate = days_to_rate_factor / spawn_time;
12811  static constexpr int radius_spawn_range = 90;
12812  std::vector<shared_ptr_fast<npc>> npcs = overmap_buffer.get_npcs_near_player( radius_spawn_range );
12813  size_t npc_num = npcs.size();
12814  for( auto &npc : npcs ) {
12816  npc_num--;
12817  }
12818  }
12819 
12820  if( npc_num > 0 ) {
12821  // 100%, 80%, 64%, 52%, 41%, 33%...
12822  spawn_rate *= std::pow( 0.8f, npc_num );
12823  }
12824 
12825  if( !ignore_spawn_timers_and_rates && !x_in_y( spawn_rate, 100 ) ) {
12826  return;
12827  }
12828  bool spawn_allowed = false;
12830  int counter = 0;
12831  while( !spawn_allowed ) {
12832  if( counter >= 10 ) {
12833  return;
12834  }
12835  const tripoint_abs_omt u_omt = u.global_omt_location();
12836  spawn_point = u_omt + point( rng( -radius_spawn_range, radius_spawn_range ),
12837  rng( -radius_spawn_range, radius_spawn_range ) );
12838  // Only spawn random NPCs on z-level 0
12839  spawn_point.z() = 0;
12840  const oter_id oter = overmap_buffer.ter( spawn_point );
12841  // shouldn't spawn on bodies of water.
12842  if( !is_water_body( oter ) ) {
12843  spawn_allowed = true;
12844  }
12845  counter += 1;
12846  }
12847  shared_ptr_fast<npc> tmp = make_shared_fast<npc>();
12848  tmp->normalize();
12849  tmp->randomize();
12850 
12851  if( one_in( 100 ) ) {
12852  // Same chances and duration of flu vs. cold as for the player.
12853  if( one_in( 6 ) ) {
12854  tmp->add_effect( effect_fake_flu, rng( 3_days, 10_days ) );
12855  } else {
12856  tmp->add_effect( effect_fake_common_cold, rng( 1_days, 14_days ) );
12857  }
12858  }
12859 
12860  std::string new_fac_id = "solo_";
12861  new_fac_id += tmp->name;
12862  // create a new "lone wolf" faction for this one NPC
12863  faction *new_solo_fac = faction_manager_ptr->add_new_faction( tmp->name, faction_id( new_fac_id ),
12865  tmp->set_fac( new_solo_fac ? new_solo_fac->id : faction_no_faction );
12866  // adds the npc to the correct overmap.
12867  tmp->spawn_at_omt( spawn_point );
12868  overmap_buffer.insert_npc( tmp );
12869  tmp->form_opinion( u );
12870  tmp->mission = NPC_MISSION_NULL;
12871  tmp->long_term_goal_action();
12872  tmp->add_new_mission( mission::reserve_random( ORIGIN_ANY_NPC, tmp->global_omt_location(),
12873  tmp->getID() ) );
12874  // This will make the new NPC active- if its nearby to the player
12875  load_npcs();
12876 }
faction_id id
Definition: faction.h:112
void load_npcs()
Makes any nearby NPCs on the overmap active.
Definition: game.cpp:1188
static const efftype_id effect_fake_flu("fake_flu")
static const efftype_id effect_fake_common_cold("fake_common_cold")
@ ORIGIN_ANY_NPC
Definition: mission.h:49
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:753
@ NPC_MISSION_NULL
Definition: npc.h:172
bool is_water_body(const oter_id &ter)
Definition: overmap.cpp:583

References effect_fake_common_cold, effect_fake_flu, faction_manager_ptr, faction_no_faction, overmapbuffer::get_npcs_near_player(), Creature::global_omt_location(), Character::has_trait(), faction_template::id, overmapbuffer::insert_npc(), is_water_body(), load_npcs(), NPC_MISSION_NULL, calendar::once_every(), one_in(), ORIGIN_ANY_NPC, overmap_buffer, point, mission::reserve_random(), rng(), overmapbuffer::ter(), trait_NPC_STARTING_NPC, trait_NPC_STATIC_NPC, u, and x_in_y().

◆ phasing_move()

bool game::phasing_move ( const tripoint dest,
bool  via_ramp = false 
)

Definition at line 11285 of file game.cpp.

11286 {
11287  const units::energy trigger_cost = bio_probability_travel->power_trigger;
11288 
11290  u.get_power_level() < trigger_cost ) {
11291  return false;
11292  }
11293 
11294  if( dest_loc.z != u.posz() && !via_ramp ) {
11295  // No vertical phasing yet
11296  return false;
11297  }
11298 
11299  //probability travel through walls but not water
11300  tripoint dest = dest_loc;
11301  // tile is impassable
11302  int tunneldist = 0;
11303  const point d( sgn( dest.x - u.posx() ), sgn( dest.y - u.posy() ) );
11304  creature_tracker &creatures = get_creature_tracker();
11305  while( m.impassable( dest ) ||
11306  ( creatures.creature_at( dest ) != nullptr && tunneldist > 0 ) ) {
11307  //add 1 to tunnel distance for each impassable tile in the line
11308  tunneldist += 1;
11309  //Being dimensionally anchored prevents quantum shenanigans.
11312  u.add_msg_if_player( m_info, _( "You are repelled by the barrier!" ) );
11313  u.mod_power_level( -trigger_cost ); //cost of tunneling one tile.
11314  return false;
11315  }
11316  if( tunneldist * trigger_cost >
11317  u.get_power_level() ) { //oops, not enough energy! Tunneling costs 250 bionic power per impassable tile
11318  add_msg( _( "You try to quantum tunnel through the barrier but are reflected! Try again with more energy!" ) );
11319  u.mod_power_level( -trigger_cost );
11320  return false;
11321  }
11322  if( tunneldist > 24 ) {
11323  add_msg( m_info, _( "It's too dangerous to tunnel that far!" ) );
11324  u.mod_power_level( -trigger_cost );
11325  return false;
11326  }
11327 
11328  dest.x += d.x;
11329  dest.y += d.y;
11330  }
11331 
11332  if( tunneldist != 0 ) {
11333  if( u.in_vehicle ) {
11334  m.unboard_vehicle( u.pos() );
11335  }
11336 
11337  add_msg( _( "You quantum tunnel through the %d-tile wide barrier!" ), tunneldist );
11338  //tunneling costs 250 bionic power per impassable tile
11339  u.mod_power_level( -( tunneldist * trigger_cost ) );
11340  u.mod_moves( -to_moves<int>( 1_seconds ) ); //tunneling takes exactly one second
11341  u.setpos( dest );
11342 
11343  if( m.veh_at( u.pos() ).part_with_feature( "BOARDABLE", true ) ) {
11344  m.board_vehicle( u.pos(), &u );
11345  }
11346 
11348  on_move_effects();
11349  m.creature_on_trap( u );
11350  return true;
11351  }
11352 
11353  return false;
11354 }
bool worn_with_flag(const flag_id &flag, const bodypart_id &bp) const
Returns true if the player is wearing an item with the given flag.
void on_move_effects()
Definition: game.cpp:11654
void board_vehicle(const tripoint &p, Character *pl)
Definition: map.cpp:1361
constexpr int sgn(const T x)
Definition: enums.h:10
const flag_id flag_DIMENSIONAL_ANCHOR("DIMENSIONAL_ANCHOR")
static const bionic_id bio_probability_travel("bio_probability_travel")

References _, add_msg(), Character::add_msg_if_player(), bio_probability_travel, map::board_vehicle(), creature_tracker::creature_at(), map::creature_on_trap(), flag_DIMENSIONAL_ANCHOR, get_creature_tracker, Character::get_power_level(), avatar::grab(), Character::has_active_bionic(), Character::has_flag(), map::impassable(), Character::in_vehicle, m, m_info, Creature::mod_moves(), Character::mod_power_level(), NONE, on_move_effects(), optional_vpart_position::part_with_feature(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), bionic_data::power_trigger, Creature::setpos(), sgn(), u, map::unboard_vehicle(), map::veh_at(), Character::worn_with_flag(), point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

◆ pickup() [1/2]

void game::pickup ( )
private

Definition at line 6319 of file game.cpp.

6320 {
6321  // Prompt for which adjacent/current tile to pick up items from
6322  const std::optional<tripoint> where_ = choose_adjacent_highlight( _( "Pick up items where?" ),
6323  _( "There is nothing to pick up nearby." ),
6324  ACTION_PICKUP, false );
6325  if( !where_ ) {
6326  return;
6327  }
6328  // Pick up items only from the selected tile
6329  u.pick_up( game_menus::inv::pickup( u, *where_ ) );
6330 }
void pick_up(const drop_locations &what)
Assigns character activity to pick up items from the given drop_locations.
drop_locations pickup(avatar &you, const std::optional< tripoint > &target=std::nullopt, const std::vector< drop_location > &selection={})
Select items to pick up.

References _, ACTION_PICKUP, choose_adjacent_highlight(), Character::pick_up(), game_menus::inv::pickup(), and u.

Referenced by do_regular_action(), and examine().

◆ pickup() [2/2]

void game::pickup ( const tripoint p)

Definition at line 6338 of file game.cpp.

6339 {
6340  // Highlight target
6341  shared_ptr_fast<game::draw_callback_t> hilite_cb = make_shared_fast<game::draw_callback_t>( [&]() {
6342  m.drawsq( w_terrain, p, drawsq_params().highlight( true ) );
6343  } );
6344  add_draw_callback( hilite_cb );
6345 
6346  // Pick up items only from the selected tile
6348 }

References add_draw_callback(), map::drawsq(), m, Character::pick_up(), game_menus::inv::pickup(), u, and w_terrain.

◆ pickup_all()

void game::pickup_all ( )
private

Definition at line 6332 of file game.cpp.

6333 {
6334  // Pick up items from current and all adjacent tiles
6336 }

References Character::pick_up(), game_menus::inv::pickup(), and u.

Referenced by do_regular_action().

◆ place_critter_around() [1/2]

monster * game::place_critter_around ( const mtype_id id,
const tripoint center,
int  radius 
)

Definition at line 5219 of file game.cpp.

5220 {
5221  // TODO: change this into an assert, it must never happen.
5222  if( id.is_null() ) {
5223  return nullptr;
5224  }
5225  shared_ptr_fast<monster> mon = make_shared_fast<monster>( id );
5226  mon->ammo = mon->type->starting_ammo;
5227  return place_critter_around( mon, center, radius );
5228 }
monster * place_critter_around(const mtype_id &id, const tripoint &center, int radius)
Definition: game.cpp:5219

References center.

Referenced by place_critter_at(), revive_corpse(), and start_game().

◆ place_critter_around() [2/2]

monster * game::place_critter_around ( const shared_ptr_fast< monster > &  mon,
const tripoint center,
int  radius,
bool  forced = false 
)

Definition at line 5230 of file game.cpp.

5234 {
5235  std::optional<tripoint> where;
5236  if( forced || can_place_monster( *mon, center ) ) {
5237  where = center;
5238  }
5239 
5240  // This loop ensures the monster is placed as close to the center as possible,
5241  // but all places that equally far from the center have the same probability.
5242  for( int r = 1; r <= radius && !where; ++r ) {
5243  where = choose_where_to_place_monster( *mon, m.points_in_radius( center, r ) );
5244  }
5245 
5246  if( !where ) {
5247  return nullptr;
5248  }
5249  mon->spawn( *where );
5250  return critter_tracker->add( mon ) ? mon.get() : nullptr;
5251 }
static std::optional< tripoint > choose_where_to_place_monster(const monster &mon, const tripoint_range< tripoint > &range)
Definition: game.cpp:5201

References can_place_monster(), center, choose_where_to_place_monster(), critter_tracker, m, and map::points_in_radius().

◆ place_critter_at() [1/2]

monster * game::place_critter_at ( const mtype_id id,
const tripoint p 
)

Adds critters to the reality bubble, creating them if necessary.

Functions taking a id parameter will construct a monster based on that id, (with default properties). Functions taking a mon parameter will use the supplied monster instance instead (which must not be null). Note: the monster will not be upgraded by these functions, it is placed as is.

place_critter_at will place the creature exactly at the given point.

place_critter_around will place the creature around the center p within the given radius (radius 0 means only the center point is used). The chosen point will be as close to the center as possible.

place_critter_within will place the creature at a random point within that given range. (All points within have equal probability.)

Returns
All functions return null if the creature could not be placed (usually because the target is not suitable for it: may be a solid wall, or air, or already occupied by some creature). If the creature has been placed, it returns a pointer to it (which is the same as the one contained in mon).

Definition at line 5209 of file game.cpp.

5210 {
5211  return place_critter_around( id, p, 0 );
5212 }

References place_critter_around().

◆ place_critter_at() [2/2]

monster * game::place_critter_at ( const shared_ptr_fast< monster > &  mon,
const tripoint p 
)

Definition at line 5214 of file game.cpp.

5215 {
5216  return place_critter_around( mon, p, 0 );
5217 }

References place_critter_around().

◆ place_critter_within() [1/2]

monster * game::place_critter_within ( const mtype_id id,
const tripoint_range< tripoint > &  range 
)

Definition at line 5253 of file game.cpp.

5254 {
5255  // TODO: change this into an assert, it must never happen.
5256  if( id.is_null() ) {
5257  return nullptr;
5258  }
5259  return place_critter_within( make_shared_fast<monster>( id ), range );
5260 }
monster * place_critter_within(const mtype_id &id, const tripoint_range< tripoint > &range)
Definition: game.cpp:5253

◆ place_critter_within() [2/2]

monster * game::place_critter_within ( const shared_ptr_fast< monster > &  mon,
const tripoint_range< tripoint > &  range 
)

Definition at line 5262 of file game.cpp.

5264 {
5265  const std::optional<tripoint> where = choose_where_to_place_monster( *mon, range );
5266  if( !where ) {
5267  return nullptr;
5268  }
5269  mon->spawn( *where );
5270  return critter_tracker->add( mon ) ? mon.get() : nullptr;
5271 }

References choose_where_to_place_monster(), and critter_tracker.

◆ place_player()

point game::place_player ( const tripoint dest,
bool  quick = false 
)
Dexterity increases chance of avoiding cuts on sharp terrain

Definition at line 10870 of file game.cpp.

10871 {
10872  const optional_vpart_position vp1 = m.veh_at( dest_loc );
10873  if( const std::optional<std::string> label = vp1.get_label() ) {
10874  add_msg( m_info, _( "Label here: %s" ), *label );
10875  }
10876  std::string signage = m.get_signage( dest_loc );
10877  if( !signage.empty() ) {
10878  if( !u.has_trait( trait_ILLITERATE ) ) {
10879  add_msg( m_info, _( "The sign says: %s" ), signage );
10880  } else {
10881  add_msg( m_info, _( "There is a sign here, but you are unable to read it." ) );
10882  }
10883  }
10884  if( m.has_graffiti_at( dest_loc ) ) {
10885  if( !u.has_trait( trait_ILLITERATE ) ) {
10886  add_msg( m_info, _( "Written here: %s" ), m.graffiti_at( dest_loc ) );
10887  } else {
10888  add_msg( m_info, _( "Something is written here, but you are unable to read it." ) );
10889  }
10890  }
10891  // TODO: Move the stuff below to a Character method so that NPCs can reuse it
10892  if( m.has_flag( ter_furn_flag::TFLAG_ROUGH, dest_loc ) && ( !u.in_vehicle ) &&
10893  ( !u.is_mounted() ) ) {
10894  if( one_in( 5 ) && u.get_armor_type( damage_bash, bodypart_id( "foot_l" ) ) < rng( 2, 5 ) ) {
10895  add_msg( m_bad, _( "You hurt your left foot on the %s!" ),
10896  m.has_flag_ter( ter_furn_flag::TFLAG_ROUGH, dest_loc ) ? m.tername( dest_loc ) : m.furnname(
10897  dest_loc ) );
10898  u.deal_damage( nullptr, bodypart_id( "foot_l" ), damage_instance( damage_cut, 1 ) );
10899  }
10900  if( one_in( 5 ) && u.get_armor_type( damage_bash, bodypart_id( "foot_r" ) ) < rng( 2, 5 ) ) {
10901  add_msg( m_bad, _( "You hurt your right foot on the %s!" ),
10902  m.has_flag_ter( ter_furn_flag::TFLAG_ROUGH, dest_loc ) ? m.tername( dest_loc ) : m.furnname(
10903  dest_loc ) );
10904  u.deal_damage( nullptr, bodypart_id( "foot_l" ), damage_instance( damage_cut, 1 ) );
10905  }
10906  }
10907  ///\EFFECT_DEX increases chance of avoiding cuts on sharp terrain
10908  if( m.has_flag( ter_furn_flag::TFLAG_SHARP, dest_loc ) && !one_in( 3 ) &&
10909  !x_in_y( 1 + u.dex_cur / 2.0, 40 ) &&
10910  ( !u.in_vehicle && !m.veh_at( dest_loc ) ) && ( !u.has_proficiency( proficiency_prof_parkour ) ||
10911  one_in( 4 ) ) && ( u.has_trait( trait_THICKSKIN ) ? !one_in( 8 ) : true ) ) {
10912  const int sharp_damage = rng( 1, 10 );
10913  if( u.is_mounted() ) {
10914  if( u.mounted_creature->get_armor_type( damage_cut, bodypart_id( "torso" ) ) < sharp_damage &&
10915  u.mounted_creature->get_hp() > sharp_damage ) {
10916  add_msg( _( "Your %s gets cut!" ), u.mounted_creature->get_name() );
10917  u.mounted_creature->apply_damage( nullptr, bodypart_id( "torso" ), sharp_damage );
10918  }
10919  } else {
10920  if( u.get_hp() > sharp_damage ) {
10922  if( u.deal_damage( nullptr, bp,
10923  damage_instance( damage_cut, sharp_damage ) ).total_damage() > 0 ) {
10924  //~ 1$s - bodypart name in accusative, 2$s is terrain name.
10925  add_msg( m_bad, _( "You cut your %1$s on the %2$s!" ),
10927  m.has_flag_ter( ter_furn_flag::TFLAG_SHARP, dest_loc ) ? m.tername( dest_loc ) : m.furnname(
10928  dest_loc ) );
10930  const int chance_in = u.has_trait( trait_INFRESIST ) ? 1024 : 256;
10931  if( one_in( chance_in ) ) {
10932  u.add_effect( effect_tetanus, 1_turns, true );
10933  }
10934  }
10935  }
10936  }
10937  }
10938  }
10939  if( m.has_flag( ter_furn_flag::TFLAG_UNSTABLE, dest_loc ) &&
10940  !u.is_mounted() && !m.has_vehicle_floor( dest_loc ) ) {
10941  u.add_effect( effect_bouldering, 1_turns, true );
10942  } else if( u.has_effect( effect_bouldering ) ) {
10944  }
10946  u.add_effect( effect_no_sight, 1_turns, true );
10947  } else if( u.has_effect( effect_no_sight ) ) {
10949  }
10950 
10951  // If we moved out of the nonant, we need update our map data
10953  add_msg( _( "The water puts out the flames!" ) );
10955  if( u.is_mounted() ) {
10956  monster *mon = u.mounted_creature.get();
10957  if( mon->has_effect( effect_onfire ) ) {
10958  mon->remove_effect( effect_onfire );
10959  }
10960  }
10961  }
10962 
10963  if( monster *const mon_ptr = get_creature_tracker().creature_at<monster>( dest_loc ) ) {
10964  // We displaced a monster. It's probably a bug if it wasn't a friendly mon...
10965  // Immobile monsters can't be displaced.
10966  monster &critter = *mon_ptr;
10967  // TODO: handling for ridden creatures other than players mount.
10968  if( !critter.has_effect( effect_ridden ) ) {
10969  if( u.is_mounted() ) {
10970  std::vector<tripoint> maybe_valid;
10971  for( const tripoint &jk : m.points_in_radius( critter.pos(), 1 ) ) {
10972  if( is_empty( jk ) ) {
10973  maybe_valid.push_back( jk );
10974  }
10975  }
10976  bool moved = false;
10977  while( !maybe_valid.empty() ) {
10978  if( critter.move_to( random_entry_removed( maybe_valid ) ) ) {
10979  add_msg( _( "You push the %s out of the way." ), critter.name() );
10980  moved = true;
10981  }
10982  }
10983  if( !moved ) {
10984  add_msg( _( "There is no room to push the %s out of the way." ), critter.name() );
10985  return u.pos().xy();
10986  }
10987  } else {
10988  // Force the movement even though the player is there right now.
10989  const bool moved = critter.move_to( u.pos(), /*force=*/false, /*step_on_critter=*/true );
10990  if( moved ) {
10991  add_msg( _( "You displace the %s." ), critter.name() );
10992  } else {
10993  add_msg( _( "You cannot move the %s out of the way." ), critter.name() );
10994  return u.pos().xy();
10995  }
10996  }
10997  } else if( !u.has_effect( effect_riding ) ) {
10998  add_msg( _( "You cannot move the %s out of the way." ), critter.name() );
10999  return u.pos().xy();
11000  }
11001  }
11002 
11003  // If the player is in a vehicle, unboard them from the current part
11004  bool was_in_control_same_pos = false;
11005  if( u.in_vehicle ) {
11006  if( u.pos() == dest_loc ) {
11007  was_in_control_same_pos = true;
11008  } else {
11009  m.unboard_vehicle( u.pos() );
11010  }
11011  }
11012  // Move the player
11013  // Start with z-level, to make it less likely that old functions (2D ones) freak out
11014  bool z_level_changed = false;
11015  if( dest_loc.z != m.get_abs_sub().z() ) {
11016  z_level_changed = vertical_shift( dest_loc.z );
11017  }
11018 
11019  if( u.is_hauling() && ( !m.can_put_items( dest_loc ) ||
11021  vp1 ) ) {
11022  u.stop_hauling();
11023  }
11024  u.setpos( dest_loc );
11025  if( u.is_mounted() ) {
11026  monster *mon = u.mounted_creature.get();
11027  mon->setpos( dest_loc );
11028  mon->process_triggers();
11029  m.creature_in_field( *mon );
11030  }
11031  point submap_shift = update_map( u, z_level_changed );
11032  // Important: don't use dest_loc after this line. `update_map` may have shifted the map
11033  // and dest_loc was not adjusted and therefore is still in the un-shifted system and probably wrong.
11034  // If you must use it you can calculate the position in the new, shifted system with
11035  // adjusted_pos = ( old_pos.x - submap_shift.x * SEEX, old_pos.y - submap_shift.y * SEEY, old_pos.z )
11036 
11037  //Auto pulp or butcher and Auto foraging
11038  if( !quick && get_option<bool>( "AUTO_FEATURES" ) && mostseen == 0 && !u.is_mounted() ) {
11039  static constexpr std::array<direction, 8> adjacentDir = {
11042  };
11043 
11044  const std::string forage_type = get_option<std::string>( "AUTO_FORAGING" );
11045  if( forage_type != "off" ) {
11046  const auto forage = [&]( const tripoint & pos ) {
11047  const ter_t &xter_t = *m.ter( pos );
11048  const furn_t &xfurn_t = *m.furn( pos );
11049  const bool forage_everything = forage_type == "all";
11050  const bool forage_bushes = forage_everything || forage_type == "bushes";
11051  const bool forage_trees = forage_everything || forage_type == "trees";
11052  const bool forage_crops = forage_everything || forage_type == "crops";
11053  if( !xter_t.can_examine( pos ) && !xfurn_t.can_examine( pos ) ) {
11054  return;
11055  } else if( ( forage_bushes && xter_t.has_examine( iexamine::shrub_marloss ) ) ||
11056  ( forage_bushes && xter_t.has_examine( iexamine::shrub_wildveggies ) ) ||
11057  ( forage_bushes && xter_t.has_examine( iexamine::harvest_ter_nectar ) ) ||
11058  ( forage_trees && xter_t.has_examine( iexamine::tree_marloss ) ) ||
11059  ( forage_trees && xter_t.has_examine( iexamine::harvest_ter ) ) ||
11060  ( forage_trees && xter_t.has_examine( iexamine::harvest_ter_nectar ) ) ||
11061  ( forage_crops && xter_t.has_examine( iexamine::harvest_plant_ex ) )
11062  ) {
11063  xter_t.examine( u, pos );
11064  } else if( ( forage_everything && xfurn_t.has_examine( iexamine::harvest_furn ) ) ||
11065  ( forage_everything && xfurn_t.has_examine( iexamine::harvest_furn_nectar ) ) ||
11066  ( forage_crops && xfurn_t.has_examine( iexamine::harvest_plant_ex ) )
11067  ) {
11068  xfurn_t.examine( u, pos );
11069  }
11070  };
11071 
11072  for( const direction &elem : adjacentDir ) {
11073  forage( u.pos() + displace_XY( elem ) );
11074  }
11075  }
11076 
11077  const std::string pulp_butcher = get_option<std::string>( "AUTO_PULP_BUTCHER" );
11078  if( pulp_butcher == "butcher" &&
11079  u.max_quality( qual_BUTCHER, PICKUP_RANGE ) > INT_MIN ) {
11080  std::vector<item *> corpses;
11081 
11082  for( item &it : m.i_at( u.pos() ) ) {
11083  corpses.push_back( &it );
11084  }
11085 
11086  if( !corpses.empty() ) {
11087  u.assign_activity( ACT_BUTCHER, 0, true );
11088  for( item *it : corpses ) {
11089  u.activity.targets.emplace_back( map_cursor( u.pos() ), it );
11090  }
11091  }
11092  } else if( pulp_butcher == "pulp" || pulp_butcher == "pulp_adjacent" ||
11093  pulp_butcher == "pulp_zombie_only" || pulp_butcher == "pulp_adjacent_zombie_only" ) {
11094  const bool acid_immune = u.is_immune_damage( damage_acid ) || u.is_immune_field( fd_acid );
11095  const auto pulp = [&]( const tripoint & pos ) {
11096  for( const item &maybe_corpse : m.i_at( pos ) ) {
11097  if( maybe_corpse.is_corpse() && maybe_corpse.can_revive() &&
11098  ( !maybe_corpse.get_mtype()->bloodType().obj().has_acid || acid_immune ) ) {
11099 
11100  if( pulp_butcher == "pulp_zombie_only" || pulp_butcher == "pulp_adjacent_zombie_only" ) {
11101  if( !maybe_corpse.get_mtype()->has_flag( mon_flag_REVIVES ) ) {
11102  continue;
11103  }
11104  }
11105 
11108  u.activity.auto_resume = true;
11109  u.activity.str_values.emplace_back( "auto_pulp_no_acid" );
11110  return;
11111  }
11112  }
11113  };
11114 
11115  if( pulp_butcher == "pulp_adjacent" || pulp_butcher == "pulp_adjacent_zombie_only" ) {
11116  for( const direction &elem : adjacentDir ) {
11117  pulp( u.pos() + displace_XY( elem ) );
11118  }
11119  } else {
11120  pulp( u.pos() );
11121  }
11122  }
11123  }
11124 
11125  // Auto pickup
11126  if( !quick && !u.is_mounted() && get_option<bool>( "AUTO_PICKUP" ) && !u.is_hauling() &&
11127  ( !get_option<bool>( "AUTO_PICKUP_SAFEMODE" ) ||
11129  ( m.has_items( u.pos() ) || get_option<bool>( "AUTO_PICKUP_ADJACENT" ) ) ) {
11130  Pickup::autopickup( u.pos() );
11131  }
11132 
11133  // If the new tile is a boardable part, board it
11134  if( !was_in_control_same_pos && vp1.part_with_feature( "BOARDABLE", true ) && !u.is_mounted() ) {
11135  m.board_vehicle( u.pos(), &u );
11136  }
11137 
11138  // Traps!
11139  // Try to detect.
11141  if( u.is_mounted() ) {
11143  } else {
11144  m.creature_on_trap( u );
11145  }
11146  // Drench the player if swimmable
11148  !m.has_flag_furn( "BRIDGE", u.pos() ) &&
11149  !( u.is_mounted() || ( u.in_vehicle && vp1->vehicle().can_float() ) ) ) {
11150  u.drench( 80, u.get_drenching_body_parts( false, false ),
11151  false );
11152  }
11153 
11154  // List items here
11155  if( !quick && !m.has_flag( ter_furn_flag::TFLAG_SEALED, u.pos() ) ) {
11156  if( get_option<bool>( "NO_AUTO_PICKUP_ZONES_LIST_ITEMS" ) ||
11158  if( u.is_blind() && !m.i_at( u.pos() ).empty() ) {
11159  add_msg( _( "There's something here, but you can't see what it is." ) );
11160  } else if( m.has_items( u.pos() ) ) {
11161  std::vector<std::string> names;
11162  std::vector<size_t> counts;
11163  std::vector<item> items;
11164  for( item &tmpitem : m.i_at( u.pos() ) ) {
11165 
11166  std::string next_tname = tmpitem.tname();
11167  std::string next_dname = tmpitem.display_name();
11168  bool by_charges = tmpitem.count_by_charges();
11169  bool got_it = false;
11170  for( size_t i = 0; i < names.size(); ++i ) {
11171  if( by_charges && next_tname == names[i] ) {
11172  counts[i] += tmpitem.charges;
11173  got_it = true;
11174  break;
11175  } else if( next_dname == names[i] ) {
11176  counts[i] += 1;
11177  got_it = true;
11178  break;
11179  }
11180  }
11181  if( !got_it ) {
11182  if( by_charges ) {
11183  names.push_back( tmpitem.tname( tmpitem.charges ) );
11184  counts.push_back( tmpitem.charges );
11185  } else {
11186  names.push_back( tmpitem.display_name( 1 ) );
11187  counts.push_back( 1 );
11188  }
11189  items.push_back( tmpitem );
11190  }
11191  if( names.size() > 10 ) {
11192  break;
11193  }
11194  }
11195  for( size_t i = 0; i < names.size(); ++i ) {
11196  if( !items[i].count_by_charges() ) {
11197  names[i] = items[i].display_name( counts[i] );
11198  } else {
11199  names[i] = items[i].tname( counts[i] );
11200  }
11201  }
11202  int and_the_rest = 0;
11203  for( size_t i = 0; i < names.size(); ++i ) {
11204  //~ number of items: "<number> <item>"
11205  std::string fmt = n_gettext( "%1$d %2$s", "%1$d %2$s", counts[i] );
11206  names[i] = string_format( fmt, counts[i], names[i] );
11207  // Skip the first two.
11208  if( i > 1 ) {
11209  and_the_rest += counts[i];
11210  }
11211  }
11212 
11213  if( get_option<bool>( "LOG_ITEMS_ON_THE_GROUND" ) ) {
11214  if( names.size() == 1 ) {
11215  add_msg( _( "You see here %s." ), names[0] );
11216  } else if( names.size() == 2 ) {
11217  add_msg( _( "You see here %s and %s." ), names[0], names[1] );
11218  } else if( names.size() == 3 ) {
11219  add_msg( _( "You see here %s, %s, and %s." ), names[0], names[1], names[2] );
11220  } else if( and_the_rest < 7 ) {
11221  add_msg( n_gettext( "You see here %s, %s and %d more item.",
11222  "You see here %s, %s and %d more items.",
11223  and_the_rest ),
11224  names[0], names[1], and_the_rest );
11225  } else {
11226  add_msg( _( "You see here %s and many more items." ), names[0] );
11227  }
11228  }
11229  }
11230  }
11231  }
11232 
11233  if( !was_in_control_same_pos &&
11234  ( vp1.part_with_feature( "CONTROL_ANIMAL", true ) ||
11235  vp1.part_with_feature( "CONTROLS", true ) ) && u.in_vehicle && !u.is_mounted() ) {
11236  add_msg( _( "There are vehicle controls here." ) );
11237  if( !u.has_trait( trait_WAYFARER ) ) {
11238  add_msg( m_info, _( "%s to drive." ), press_x( ACTION_CONTROL_VEHICLE ) );
11239  }
11240  } else if( vp1.part_with_feature( "CONTROLS", true ) && u.in_vehicle &&
11241  u.is_mounted() ) {
11242  add_msg( _( "There are vehicle controls here but you cannot reach them whilst mounted." ) );
11243  }
11244  return submap_shift;
11245 }
std::string body_part_name_accusative(const bodypart_id &bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:798
void drench(int saturation, const body_part_set &flags, bool ignore_waterproof)
Drenches the player with water, saturation is the percent gotten wet.
Definition: suffer.cpp:1881
bool is_immune_damage(const damage_type_id &) const override
Returns true if the player is immune to this kind of damage.
Definition: character.cpp:5908
bool is_hauling() const
Definition: character.cpp:8873
bool is_immune_field(const field_type_id &fid) const override
Returns true if we are immune to the field type with the given fid.
Definition: character.cpp:5841
void search_surroundings()
Search surrounding squares for traps (and maybe other things in the future).
void stop_hauling()
Definition: character.cpp:8860
bodypart_id get_random_body_part(bool main=false) const
Definition: creature.cpp:2506
body_part_set get_drenching_body_parts(bool upper=true, bool mid=true, bool lower=true) const
Definition: creature.cpp:2704
bool vertical_shift(int z_after)
Actual z-level movement part of vertical_move.
Definition: game.cpp:12554
bool check_zone(const zone_type_id &type, const tripoint &where) const
Definition: game.cpp:6847
bool has_flag_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:3112
std::string furnname(const tripoint &p)
Definition: map.cpp:1888
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:3122
bool has_graffiti_at(const tripoint &p) const
Definition: map.cpp:9197
bool has_vehicle_floor(const tripoint &p) const
Definition: map.cpp:2739
void creature_in_field(Creature &critter)
Apply field effects to the creature when it's on a square with fields.
Definition: map_field.cpp:1745
const std::string & graffiti_at(const tripoint &p) const
Definition: map.cpp:9181
bool has_flag_ter(const std::string &flag, const tripoint &p) const
Definition: map.cpp:3107
bool can_put_items(const tripoint &p) const
Definition: map.cpp:3087
bool move_to(const tripoint &p, bool force=false, bool step_on_critter=false, float stagger_adjustment=1.0)
Attempt to move to p.
Definition: monmove.cpp:1852
void process_triggers()
Definition: monster.cpp:1662
std::optional< std::string > get_label() const
std::vector< std::string > str_values
bool auto_resume
If true, the activity will be auto-resumed next time the player attempts an identical activity.
tripoint_abs_ms placement
const field_type_str_id fd_acid("fd_acid")
static const zone_type_id zone_type_NO_AUTO_PICKUP("NO_AUTO_PICKUP")
static const efftype_id effect_riding("riding")
static const trait_id trait_ILLITERATE("ILLITERATE")
static const trait_id trait_INFRESIST("INFRESIST")
static const proficiency_id proficiency_prof_parkour("prof_parkour")
static const activity_id ACT_BUTCHER("ACT_BUTCHER")
static const efftype_id effect_ridden("ridden")
static const efftype_id effect_bouldering("bouldering")
static const activity_id ACT_PULP("ACT_PULP")
static const efftype_id effect_tetanus("tetanus")
static const damage_type_id damage_acid("acid")
static const trait_id trait_WAYFARER("WAYFARER")
static const efftype_id effect_no_sight("no_sight")
static const json_character_flag json_flag_INFECTION_IMMUNE("INFECTION_IMMUNE")
static const trait_id trait_THICKSKIN("THICKSKIN")
static const efftype_id effect_onfire("onfire")
point displace_XY(const direction dir)
Definition: line.cpp:515
mon_flag_id mon_flag_REVIVES
Definition: mtype.cpp:140
cata_path names()
Definition: path_info.cpp:530
void autopickup(const tripoint &p)
Pick up items; 'g' or ',' or via examine()
Definition: pickup.cpp:393
const int INDEFINITELY_LONG
A number that represents the longest possible action.
void harvest_ter(Character &you, const tripoint &examp)
Definition: iexamine.cpp:2415
void shrub_wildveggies(Character &you, const tripoint &examp)
Definition: iexamine.cpp:4512
void tree_marloss(Character &you, const tripoint &examp)
Definition: iexamine.cpp:4491
void harvest_plant_ex(Character &you, const tripoint &examp)
Definition: iexamine.cpp:2652
void harvest_furn_nectar(Character &you, const tripoint &examp)
Definition: iexamine.cpp:2383
void harvest_furn(Character &you, const tripoint &examp)
Definition: iexamine.cpp:2393
void shrub_marloss(Character &you, const tripoint &examp)
Definition: iexamine.cpp:4477
void harvest_ter_nectar(Character &you, const tripoint &examp)
Definition: iexamine.cpp:2403
V random_entry_removed(C &container)
Returns a random entry in the container and removes it from the container.
Definition: rng.h:186

References _, ACT_BUTCHER, ACT_PULP, ACTION_CONTROL_VEHICLE, Character::activity, Creature::add_effect(), add_msg(), Character::assign_activity(), player_activity::auto_resume, Pickup::autopickup(), map::board_vehicle(), body_part_name_accusative(), bp, map_data_common_t::can_examine(), map::can_put_items(), check_zone(), map::creature_in_field(), map::creature_on_trap(), damage_acid, damage_bash, damage_cut, Character::deal_damage(), Character::dex_cur, displace_XY(), Character::drench(), EAST, effect_bouldering, effect_no_sight, effect_onfire, effect_ridden, effect_riding, effect_tetanus, item_stack::empty(), map_data_common_t::examine(), fd_acid, map::furn(), map::furnname(), map::get_abs_sub(), Character::get_armor_type(), get_creature_tracker, Creature::get_drenching_body_parts(), Creature::get_hp(), optional_vpart_position::get_label(), avatar::get_mon_visible(), Creature::get_random_body_part(), map::get_signage(), map::getglobal(), map::graffiti_at(), iexamine::harvest_furn(), iexamine::harvest_furn_nectar(), iexamine::harvest_plant_ex(), iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), monster_visible_info::has_dangerous_creature_in_proximity, Creature::has_effect(), map_data_common_t::has_examine(), Character::has_flag(), map::has_flag(), map::has_flag_furn(), map::has_flag_ter(), map::has_flag_ter_or_furn(), map::has_graffiti_at(), map::has_items(), Character::has_proficiency(), Character::has_trait(), map::has_vehicle_floor(), map::i_at(), Character::in_vehicle, calendar::INDEFINITELY_LONG, Character::is_blind(), is_empty(), Character::is_hauling(), Character::is_immune_damage(), Character::is_immune_field(), Character::is_mounted(), json_flag_INFECTION_IMMUNE, m, m_bad, m_info, Character::max_quality(), mon_flag_REVIVES, mostseen, Character::mounted_creature, monster::move_to(), n_gettext, monster::name(), PATH_INFO::names(), NORTH, NORTHEAST, NORTHWEST, one_in(), optional_vpart_position::part_with_feature(), PICKUP_RANGE, player_activity::placement, map::points_in_radius(), Creature::pos(), math_opers::pos(), press_x(), monster::process_triggers(), proficiency_prof_parkour, qual_BUTCHER, random_entry_removed(), Creature::remove_effect(), rng(), Character::search_surroundings(), Creature::setpos(), iexamine::shrub_marloss(), iexamine::shrub_wildveggies(), SOUTH, SOUTHEAST, SOUTHWEST, Character::stop_hauling(), player_activity::str_values, string_format(), player_activity::targets, map::ter(), map::tername(), TFLAG_DEEP_WATER, TFLAG_NO_SIGHT, TFLAG_ROUGH, TFLAG_SEALED, TFLAG_SHARP, TFLAG_SWIMMABLE, TFLAG_UNSTABLE, trait_ILLITERATE, trait_INFRESIST, trait_THICKSKIN, trait_WAYFARER, iexamine::tree_marloss(), u, map::unboard_vehicle(), update_map(), map::veh_at(), vertical_shift(), WEST, x_in_y(), tripoint::xy(), coords::coord_point_mut< Point, Subpoint, InBounds >::z(), tripoint::z, and zone_type_NO_AUTO_PICKUP.

Referenced by place_player_overmap(), and walk_move().

◆ place_player_overmap()

void game::place_player_overmap ( const tripoint_abs_omt om_dest,
bool  move_player = true 
)

Definition at line 11247 of file game.cpp.

11248 {
11249  // if player is teleporting around, they don't bring their horse with them
11250  if( u.is_mounted() ) {
11252  u.mounted_creature->remove_effect( effect_ridden );
11253  u.mounted_creature = nullptr;
11254  }
11255  // offload the active npcs.
11256  unload_npcs();
11257  for( monster &critter : all_monsters() ) {
11258  despawn_monster( critter );
11259  }
11260  if( u.in_vehicle ) {
11261  m.unboard_vehicle( u.pos() );
11262  }
11263  for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
11264  m.clear_vehicle_list( z );
11265  }
11269  // offset because load_map expects the coordinates of the top left corner, but the
11270  // player will be centered in the middle of the map.
11271  const tripoint_abs_sm map_sm_pos =
11272  project_to<coords::sm>( om_dest ) - point( HALF_MAPSIZE, HALF_MAPSIZE );
11273  const tripoint player_pos( u.pos().xy(), map_sm_pos.z() );
11274  load_map( map_sm_pos );
11275  load_npcs();
11276  m.spawn_monsters( true ); // Static monsters
11278  // update weather now as it could be different on the new location
11280  if( move_player ) {
11281  place_player( player_pos );
11282  }
11283 }
void unload_npcs()
Unloads all NPCs.
Definition: game.cpp:1243
point place_player(const tripoint &dest, bool quick=false)
Definition: game.cpp:10870
void despawn_monster(monster &critter)
Despawn a specific monster, it's stored on the overmap.
Definition: game.cpp:12750
void load_map(const tripoint_abs_sm &pos_sm, bool pump_events=false)
Load the main map at given location, see map::load, in global, absolute submap coordinates.
Definition: game.cpp:843
void update_overmap_seen()
Definition: game.cpp:12711
void spawn_monsters(bool ignore_sight, bool spawn_nonlocal=false)
Spawn monsters from submap spawn points and from the overmap.
Definition: map.cpp:9001
level_cache & access_cache(int zlev)
Definition: map.cpp:10243
void clear_vehicle_list(int zlev)
Definition: map.cpp:551
time_point nextweather
Definition: weather.h:223
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_cache_dec
Definition: level_cache.h:76
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_cache_ter
Definition: level_cache.h:77

References map::access_cache(), all_monsters(), map::clear_vehicle_list(), despawn_monster(), effect_ridden, effect_riding, map::get_abs_sub(), HALF_MAPSIZE, Character::in_vehicle, Character::is_mounted(), load_map(), load_npcs(), m, level_cache::map_memory_cache_dec, level_cache::map_memory_cache_ter, Character::mounted_creature, weather_manager::nextweather, OVERMAP_DEPTH, OVERMAP_HEIGHT, place_player(), point, Creature::pos(), map::rebuild_vehicle_level_caches(), Creature::remove_effect(), map::spawn_monsters(), calendar::turn, u, map::unboard_vehicle(), unload_npcs(), update_overmap_seen(), weather, tripoint::xy(), and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

◆ place_vehicle_nearby()

vehicle * game::place_vehicle_nearby ( const vproto_id id,
const point_abs_omt origin,
int  min_distance,
int  max_distance,
const std::vector< std::string > &  omt_search_types = {} 
)
private

Definition at line 1136 of file game.cpp.

1139 {
1140  std::vector<std::string> search_types = omt_search_types;
1141  if( search_types.empty() ) {
1142  const vehicle &veh = *id->blueprint;
1143  if( veh.max_ground_velocity() == 0 && veh.can_float() ) {
1144  search_types.emplace_back( "river" );
1145  search_types.emplace_back( "lake" );
1146  search_types.emplace_back( "ocean" );
1147  } else {
1148  search_types.emplace_back( "road" );
1149  search_types.emplace_back( "field" );
1150  }
1151  }
1152  for( const std::string &search_type : search_types ) {
1153  omt_find_params find_params;
1154  find_params.types.emplace_back( search_type, ot_match_type::type );
1155  // find nearest road
1156  find_params.min_distance = min_distance;
1157  find_params.search_range = max_distance;
1158  // if player spawns underground, park their car on the surface.
1159  const tripoint_abs_omt omt_origin( origin, 0 );
1160  for( const tripoint_abs_omt &goal : overmap_buffer.find_all( omt_origin, find_params ) ) {
1161  // try place vehicle there.
1162  tinymap target_map;
1163  target_map.load( goal, false );
1164  const tripoint tinymap_center( SEEX, SEEY, goal.z() );
1165  static constexpr std::array<units::angle, 4> angles = {{
1166  0_degrees, 90_degrees, 180_degrees, 270_degrees
1167  }
1168  };
1169  vehicle *veh = target_map.add_vehicle( id, tinymap_center, random_entry( angles ),
1170  rng( 50, 80 ), 0, false );
1171  if( veh ) {
1172  tripoint abs_local = m.getlocal( target_map.getabs( tinymap_center ) );
1173  veh->sm_pos = ms_to_sm_remain( abs_local );
1174  veh->pos = abs_local.xy();
1175 
1176  veh->unlock(); // always spawn unlocked
1177  veh->toggle_tracking(); // always spawn tracked
1178 
1179  target_map.save();
1180  return veh;
1181  }
1182  }
1183  }
1184  return nullptr;
1185 }
std::vector< tripoint_abs_omt > find_all(const tripoint_abs_omt &origin, const omt_find_params &params)
Find all places with the specific overmap terrain type.
Tinymap is a small version of the map which covers a single overmap terrain (OMT) tile,...
Definition: map.h:2423
void save()
Add currently loaded submaps (in grid) to the mapbuffer.
Definition: map.cpp:7879
tripoint getabs(const tripoint &p) const
Definition: map.h:2669
void load(const tripoint_abs_omt &w, bool update_vehicles, bool pump_events=false)
Definition: map.h:2447
vehicle * add_vehicle(const vproto_id &type, const tripoint &p, const units::angle &dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
Definition: map.h:2650
tripoint sm_pos
Submap coordinates of the currently loaded submap (see game::m) that contains this vehicle.
Definition: vehicle.h:2261
int max_ground_velocity(bool fueled=true) const
Definition: vehicle.cpp:3879
bool can_float() const
can_float does the vehicle have freeboard or does it overflow with water?
Definition: vehicle.cpp:4349
void unlock(int part_index)
Unlocks a lockable, closed part at the specified index.
void toggle_tracking()
point ms_to_sm_remain(int &x, int &y)
constexpr int SEEY
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:104
std::vector< std::pair< std::string, ot_match_type > > types

References tinymap::add_vehicle(), vehicle::can_float(), overmapbuffer::find_all(), tinymap::getabs(), map::getlocal(), tinymap::load(), m, vehicle::max_ground_velocity(), omt_find_params::min_distance, ms_to_sm_remain(), overmap_buffer, vehicle::pos, random_entry(), rng(), tinymap::save(), omt_find_params::search_range, SEEX, SEEY, vehicle::sm_pos, vehicle::toggle_tracking(), type, omt_find_params::types, vehicle::unlock(), and tripoint::xy().

Referenced by start_game().

◆ point_selection_menu()

std::optional< tripoint > game::point_selection_menu ( const std::vector< tripoint > &  pts,
bool  up = true 
)

Definition at line 11913 of file game.cpp.

11914 {
11915  if( pts.empty() ) {
11916  debugmsg( "point_selection_menu called with empty point set" );
11917  return std::nullopt;
11918  }
11919 
11920  if( pts.size() == 1 ) {
11921  return pts[0];
11922  }
11923 
11924  const tripoint upos = get_player_character().pos();
11925  uilist pmenu;
11926  pmenu.title = _( "Climb where?" );
11927  int num = 0;
11928  for( const tripoint &pt : pts ) {
11929  // TODO: Sort the menu so that it can be used with numpad directions
11930  const std::string &dir_arrow = direction_arrow( direction_from( upos.xy(), pt.xy() ) );
11931  const std::string &dir_name = direction_name( direction_from( upos.xy(), pt.xy() ) );
11932  const std::string &up_or_down = up ? _( "Climb up %s (%s)" ) : _( "Climb down %s (%s)" );
11933  // TODO: Inform player what is on said tile
11934  // But don't just print terrain name (in many cases it will be "open air")
11935  pmenu.addentry( num++, true, MENU_AUTOASSIGN, string_format( up_or_down, dir_name, dir_arrow ) );
11936  }
11937 
11938  pmenu.query();
11939  const int ret = pmenu.ret;
11940  if( ret < 0 || ret >= num ) {
11941  return std::nullopt;
11942  }
11943 
11944  return pts[ret];
11945 }
std::string title
Definition: ui.h:418
std::string direction_arrow(const direction dir)
Definition: line.cpp:622

References _, uilist::addentry(), debugmsg, direction_arrow(), direction_from(), direction_name(), get_player_character, MENU_AUTOASSIGN, Creature::pos(), uilist::query(), cata::hash64_detail::ret, uilist::ret, string_format(), uilist::title, and tripoint::xy().

Referenced by do_regular_action(), and vertical_move().

◆ portal_storm_query()

bool game::portal_storm_query ( distraction_type  type,
const std::string &  text 
)

Definition at line 1510 of file game.cpp.

1511 {
1512  if( u.has_distant_destination() ) {
1513  if( cancel_auto_move( u, text ) ) {
1514  return true;
1515  } else {
1517  return false;
1518  }
1519  }
1521  return false;
1522  }
1523 
1524  static const std::vector<nc_color> color_list = {
1527  };
1528  const nc_color color = random_entry( color_list );
1529 
1530  query_popup()
1531  .context( "YES_QUERY" )
1532  .message( "%s", text )
1533  .option( "YES0" )
1534  .option( "YES1" )
1535  .option( "YES2" )
1536  .default_color( color )
1537  .query();
1538 
1539  // ensure it never happens again during this activity - shouldn't be an issue anyway
1541  for( player_activity &activity : u.backlog ) {
1542  activity.ignore_distraction( type );
1543  }
1544 
1546  refresh_display();
1547 
1548  return false;
1549 }
query_popup & default_color(const nc_color &d_color)
Specify the default message color.
Definition: popup.cpp:216

References ACT_TRAVELLING, Character::activity, Character::backlog, c_blue, c_green, c_light_blue, c_light_green, c_light_red, c_red, c_yellow, cancel_auto_move(), color(), query_popup::context(), query_popup::default_color(), Character::get_auto_move_route(), Character::has_distant_destination(), player_activity::ignore_distraction(), player_activity::is_distraction_ignored(), query_popup::message(), query_popup::option(), query_popup::query(), random_entry(), ui_manager::redraw(), refresh_display(), Character::set_destination(), type, and u.

◆ pre_print_all_tile_info()

void game::pre_print_all_tile_info ( const tripoint lp,
const catacurses::window w_info,
int &  line,
int  last_line,
const visibility_variables cache 
)

Definition at line 7575 of file game.cpp.

7578 {
7579  // get global area info according to look_around caret position
7580  // TODO: fix point types
7582  lp ) ) ) );
7583  // we only need the area name and then pass it to print_all_tile_info() function below
7584  const std::string area_name = cur_ter_m->get_name();
7585  print_all_tile_info( lp, w_info, area_name, 1, first_line, last_line, cache );
7586 }
void print_all_tile_info(const tripoint &lp, const catacurses::window &w_look, const std::string &area_name, int column, int &line, int last_line, const visibility_variables &cache)
Definition: game.cpp:6472
point ms_to_omt_copy(const point &p)
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:726
std::string get_name() const
Definition: omdata.h:330

References oter_t::get_name(), map::getabs(), m, ms_to_omt_copy(), overmap_buffer, print_all_tile_info(), and overmapbuffer::ter().

Referenced by look_around().

◆ print_all_tile_info()

void game::print_all_tile_info ( const tripoint lp,
const catacurses::window w_look,
const std::string &  area_name,
int  column,
int &  line,
int  last_line,
const visibility_variables cache 
)

Definition at line 6472 of file game.cpp.

6477 {
6479  const bool inbounds = m.inbounds( lp );
6480  if( inbounds ) {
6481  visibility = m.get_visibility( m.apparent_light_at( lp, cache ), cache );
6482  }
6483  const Creature *creature = get_creature_tracker().creature_at( lp, true );
6484  switch( visibility ) {
6485  case visibility_type::CLEAR: {
6486  const optional_vpart_position vp = m.veh_at( lp );
6487  print_terrain_info( lp, w_look, area_name, column, line );
6488  print_fields_info( lp, w_look, column, line );
6489  print_trap_info( lp, w_look, column, line );
6490  print_part_con_info( lp, w_look, column, line );
6491  print_creature_info( creature, w_look, column, line, last_line );
6492  print_vehicle_info( veh_pointer_or_null( vp ), vp ? vp->part_index() : -1, w_look, column, line,
6493  last_line );
6494  print_items_info( lp, w_look, column, line, last_line );
6495  print_graffiti_info( lp, w_look, column, line, last_line );
6496  }
6497  break;
6500  case visibility_type::DARK:
6501  case visibility_type::LIT:
6503  print_visibility_info( w_look, column, line, visibility );
6504 
6505  if( creature != nullptr ) {
6506  std::vector<std::string> buf;
6507  if( u.sees_with_infrared( *creature ) ) {
6508  creature->describe_infrared( buf );
6509  } else if( u.sees_with_specials( *creature ) ) {
6510  creature->describe_specials( buf );
6511  }
6512  for( const std::string &s : buf ) {
6513  mvwprintw( w_look, point( 1, ++line ), s );
6514  }
6515  }
6516  break;
6517  }
6518  if( !inbounds ) {
6519  return;
6520  }
6521  const int max_width = getmaxx( w_look ) - column - 1;
6522 
6523  std::string this_sound = sounds::sound_at( lp );
6524  if( !this_sound.empty() ) {
6525  const int lines = fold_and_print( w_look, point( 1, ++line ), max_width, c_light_gray,
6526  _( "From here you heard %s" ),
6527  this_sound );
6528  line += lines - 1;
6529  } else {
6530  // Check other z-levels
6531  tripoint tmp = lp;
6532  for( tmp.z = -OVERMAP_DEPTH; tmp.z <= OVERMAP_HEIGHT; tmp.z++ ) {
6533  if( tmp.z == lp.z ) {
6534  continue;
6535  }
6536 
6537  std::string zlev_sound = sounds::sound_at( tmp );
6538  if( !zlev_sound.empty() ) {
6539  const int lines = fold_and_print( w_look, point( 1, ++line ), max_width, c_light_gray,
6540  tmp.z > lp.z ?
6541  _( "From above you heard %s" ) : _( "From below you heard %s" ), zlev_sound );
6542  line += lines - 1;
6543  }
6544  }
6545  }
6546 }
void print_fields_info(const tripoint &lp, const catacurses::window &w_look, int column, int &line)
Definition: game.cpp:6706
void print_part_con_info(const tripoint &lp, const catacurses::window &w_look, int column, int &line)
Definition: game.cpp:6741
void print_terrain_info(const tripoint &lp, const catacurses::window &w_look, const std::string &area_name, int column, int &line)
Definition: game.cpp:6577
void print_graffiti_info(const tripoint &lp, const catacurses::window &w_look, int column, int &line, int last_line)
Definition: game.cpp:6830
void print_creature_info(const Creature *creature, const catacurses::window &w_look, int column, int &line, int last_line)
Definition: game.cpp:6760
void print_vehicle_info(const vehicle *veh, int veh_part, const catacurses::window &w_look, int column, int &line, int last_line)
Definition: game.cpp:6769
void print_items_info(const tripoint &lp, const catacurses::window &w_look, int column, int &line, int last_line)
Definition: game.cpp:6793
void print_visibility_info(const catacurses::window &w_look, int column, int &line, visibility_type visibility)
Definition: game.cpp:6548
void print_trap_info(const tripoint &lp, const catacurses::window &w_look, int column, int &line)
Definition: game.cpp:6729
std::string sound_at(const tripoint &location)
Definition: sounds.cpp:825
int fold_and_print(const catacurses::window &w, const point &begin, int width, const nc_color &base_color, const std::string &text, const char split)
Fold and print text in the given window.
Definition: output.cpp:379

References _, map::apparent_light_at(), BOOMER, BOOMER_DARK, c_light_gray, CLEAR, creature, creature_tracker::creature_at(), DARK, fold_and_print(), get_creature_tracker, map::get_visibility(), catacurses::getmaxx(), HIDDEN, map::inbounds(), line, LIT, m, catacurses::mvwprintw(), OVERMAP_DEPTH, OVERMAP_HEIGHT, point, print_creature_info(), print_fields_info(), print_graffiti_info(), print_items_info(), print_part_con_info(), print_terrain_info(), print_trap_info(), print_vehicle_info(), print_visibility_info(), Character::sees_with_infrared(), Character::sees_with_specials(), sounds::sound_at(), u, map::veh_at(), veh_pointer_or_null(), and tripoint::z.

Referenced by pre_print_all_tile_info().

◆ print_creature_info()

void game::print_creature_info ( const Creature creature,
const catacurses::window w_look,
int  column,
int &  line,
int  last_line 
)
private

Definition at line 6760 of file game.cpp.

6762 {
6763  int vLines = last_line - line;
6764  if( creature != nullptr && ( u.sees( *creature ) || creature == &u ) ) {
6765  line = creature->print_info( w_look, ++line, vLines, column );
6766  }
6767 }

References creature, line, Character::sees(), and u.

Referenced by print_all_tile_info().

◆ print_fields_info()

void game::print_fields_info ( const tripoint lp,
const catacurses::window w_look,
int  column,
int &  line 
)
private

Definition at line 6706 of file game.cpp.

6708 {
6709  const field &tmpfield = m.field_at( lp );
6710  for( const auto &fld : tmpfield ) {
6711  const field_entry &cur = fld.second;
6712  if( fld.first.obj().has_fire && ( m.has_flag( ter_furn_flag::TFLAG_FIRE_CONTAINER, lp ) ||
6713  m.ter( lp ) == ter_t_pit_shallow || m.ter( lp ) == ter_t_pit ) ) {
6714  const int max_width = getmaxx( w_look ) - column - 2;
6715  int lines = fold_and_print( w_look, point( column, ++line ), max_width, cur.color(),
6716  get_fire_fuel_string( lp ) ) - 1;
6717  line += lines;
6718  } else {
6719  mvwprintz( w_look, point( column, ++line ), cur.color(), cur.name() );
6720  }
6721  }
6722 
6723  int size = std::distance( tmpfield.begin(), tmpfield.end() );
6724  if( size > 0 ) {
6725  mvwprintz( w_look, point( column, ++line ), c_white, "\n" );
6726  }
6727 }
An active or passive effect existing on a tile.
Definition: field.h:21
nc_color color() const
Definition: field.cpp:17
std::string name() const
Definition: field.h:67
static const ter_str_id ter_t_pit("t_pit")
static const ter_str_id ter_t_pit_shallow("t_pit_shallow")

References field::begin(), c_white, field_entry::color(), field::end(), map::field_at(), fold_and_print(), get_fire_fuel_string(), catacurses::getmaxx(), map::has_flag(), line, m, mvwprintz(), field_entry::name(), point, om_direction::size, map::ter(), ter_t_pit, ter_t_pit_shallow, and TFLAG_FIRE_CONTAINER.

Referenced by print_all_tile_info().

◆ print_furniture_info()

void game::print_furniture_info ( const tripoint lp,
const catacurses::window w_look,
int  column,
int &  line 
)
private

Definition at line 6663 of file game.cpp.

6665 {
6666  // Do nothing if there is no furniture here
6667  if( !m.has_furn( lp ) ) {
6668  return;
6669  }
6670  const int max_width = getmaxx( w_look ) - column - 1;
6671 
6672  // Print furniture name in white
6673  std::string desc = uppercase_first_letter( m.furnname( lp ) );
6674  mvwprintz( w_look, point( column, line++ ), c_white, desc );
6675 
6676  // Print each line of furniture description in gray
6677  desc = string_format( m.furn( lp ).obj().description );
6678  std::vector<std::string> lines = foldstring( desc, max_width );
6679  int numlines = lines.size();
6680  for( int i = 0; i < numlines; i++ ) {
6681  mvwprintz( w_look, point( column, line++ ), c_light_gray, lines[i] );
6682  }
6683 
6684  // If this furniture has a crafting pseudo item, check for tool qualities and print them
6685  if( !m.furn( lp )->crafting_pseudo_item.is_empty() ) {
6686  // Make a pseudo item instance so we can use qualities_info later
6687  const item pseudo( m.furn( lp )->crafting_pseudo_item );
6688  // Set up iteminfo query to show qualities
6689  std::vector<iteminfo_parts> quality_part = { iteminfo_parts::QUALITIES };
6690  const iteminfo_query quality_query( quality_part );
6691  // Render info into info_vec
6692  std::vector<iteminfo> info_vec;
6693  pseudo.qualities_info( info_vec, &quality_query, 1, false );
6694  // Get a newline-separated string of quality info, then parse and print each line
6695  std::string quality_string = format_item_info( info_vec, {} );
6696  size_t strpos = 0;
6697  while( ( strpos = quality_string.find( '\n' ) ) != std::string::npos ) {
6698  trim_and_print( w_look, point( column, line++ ), max_width, c_light_gray,
6699  quality_string.substr( 0, strpos + 1 ) );
6700  // Delete used token
6701  quality_string.erase( 0, strpos + 1 );
6702  }
6703  }
6704 }
std::string format_item_info(const std::vector< iteminfo > &vItemDisplay, const std::vector< iteminfo > &vItemCompare)
Definition: output.cpp:1110
std::string uppercase_first_letter(const std::string &str)
Definition: output.cpp:2558
std::vector< std::string > foldstring(const std::string &str, int width, const char split)
Split the input text into separate lines and wrap long lines.
Definition: output.cpp:123
itype_id crafting_pseudo_item
Definition: mapdata.h:650
translation description
Definition: mapdata.h:511

References c_light_gray, c_white, furn_t::crafting_pseudo_item, map_data_common_t::description, foldstring(), format_item_info(), map::furn(), map::furnname(), catacurses::getmaxx(), map::has_furn(), string_id< T >::is_empty(), line, m, mvwprintz(), int_id< T >::obj(), point, QUALITIES, item::qualities_info(), string_format(), trim_and_print(), and uppercase_first_letter().

Referenced by print_terrain_info().

◆ print_graffiti_info()

void game::print_graffiti_info ( const tripoint lp,
const catacurses::window w_look,
int  column,
int &  line,
int  last_line 
)
private

Definition at line 6830 of file game.cpp.

6833 {
6834  if( line > last_line ) {
6835  return;
6836  }
6837 
6838  const int max_width = getmaxx( w_look ) - column - 2;
6839  if( m.has_graffiti_at( lp ) ) {
6840  const int lines = fold_and_print( w_look, point( column, ++line ), max_width, c_light_gray,
6841  m.ter( lp ) == ter_t_grave_new ? _( "Graffiti: %s" ) : _( "Inscription: %s" ),
6842  m.graffiti_at( lp ) );
6843  line += lines - 1;
6844  }
6845 }
static const ter_str_id ter_t_grave_new("t_grave_new")

References _, c_light_gray, fold_and_print(), catacurses::getmaxx(), map::graffiti_at(), map::has_graffiti_at(), line, m, point, map::ter(), and ter_t_grave_new.

Referenced by print_all_tile_info().

◆ print_items_info()

void game::print_items_info ( const tripoint lp,
const catacurses::window w_look,
int  column,
int &  line,
int  last_line 
)
private

Definition at line 6793 of file game.cpp.

6796 {
6797  if( !m.sees_some_items( lp, u ) ) {
6798  return;
6799  } else if( m.has_flag( ter_furn_flag::TFLAG_CONTAINER, lp ) && !m.could_see_items( lp, u ) ) {
6800  mvwprintw( w_look, point( column, ++line ), _( "You cannot see what is inside of it." ) );
6801  } else if( u.has_effect( effect_blind ) || u.worn_with_flag( flag_BLIND ) ) {
6802  mvwprintz( w_look, point( column, ++line ), c_yellow,
6803  _( "There's something there, but you can't see what it is." ) );
6804  return;
6805  } else {
6806  std::map<std::string, std::pair<int, nc_color>> item_names;
6807  for( const item &it : m.i_at( lp ) ) {
6808  add_visible_items_recursive( item_names, it );
6809  }
6810 
6811  const int max_width = getmaxx( w_look ) - column - 1;
6812  for( auto it = item_names.begin(); it != item_names.end(); ++it ) {
6813  // last line but not last item
6814  if( line + 1 >= last_line && std::next( it ) != item_names.end() ) {
6815  mvwprintz( w_look, point( column, ++line ), c_yellow, _( "More items here…" ) );
6816  break;
6817  }
6818 
6819  if( it->second.first > 1 ) {
6820  trim_and_print( w_look, point( column, ++line ), max_width, it->second.second,
6821  pgettext( "%s is the name of the item. %d is the quantity of that item.", "%s [%d]" ),
6822  it->first.c_str(), it->second.first );
6823  } else {
6824  trim_and_print( w_look, point( column, ++line ), max_width, it->second.second, it->first );
6825  }
6826  }
6827  }
6828 }
bool could_see_items(const tripoint &p, const Creature &who) const
Check if the creature could see items at p if there were any items.
Definition: map.cpp:5866
const flag_id flag_BLIND("BLIND")
static const efftype_id effect_blind("blind")
static void add_visible_items_recursive(std::map< std::string, std::pair< int, nc_color >> &item_names, const item &it)
Definition: game.cpp:6782

References _, add_visible_items_recursive(), c_yellow, map::could_see_items(), effect_blind, flag_BLIND, catacurses::getmaxx(), Creature::has_effect(), map::has_flag(), map::i_at(), line, m, catacurses::mvwprintw(), mvwprintz(), pgettext, point, map::sees_some_items(), TFLAG_CONTAINER, trim_and_print(), u, and Character::worn_with_flag().

Referenced by print_all_tile_info().

◆ print_part_con_info()

void game::print_part_con_info ( const tripoint lp,
const catacurses::window w_look,
int  column,
int &  line 
)
private

Definition at line 6741 of file game.cpp.

6744 {
6745  // TODO: fix point types
6747  std::string tr_name;
6748  if( pc != nullptr ) {
6749  const construction &built = pc->id.obj();
6750  tr_name = string_format( _( "Unfinished task: %s, %d%% complete" ), built.group->name(),
6751  pc->counter / 100000 );
6752 
6753  int const width = getmaxx( w_look ) - column - 2;
6754  fold_and_print( w_look, point( column, ++line ), width, c_white, tr_name );
6755 
6756  ++line;
6757  }
6758 }
partial_con * partial_con_at(const tripoint_bub_ms &p)
Definition: map.cpp:6244
std::string name() const
construction_group_str_id group
Definition: construction.h:47
construction_id id
Definition: construction.h:35

References _, c_white, partial_con::counter, fold_and_print(), catacurses::getmaxx(), construction::group, partial_con::id, line, m, construction_group::name(), int_id< T >::obj(), map::partial_con_at(), point, and string_format().

Referenced by print_all_tile_info().

◆ print_terrain_info()

void game::print_terrain_info ( const tripoint lp,
const catacurses::window w_look,
const std::string &  area_name,
int  column,
int &  line 
)
private

Definition at line 6577 of file game.cpp.

6579 {
6580  const int max_width = getmaxx( w_look ) - column - 1;
6581 
6582  // Print OMT type and terrain type on first two lines
6583  // if can't fit in one line.
6584  std::string tile = uppercase_first_letter( m.tername( lp ) );
6585  std::string area = uppercase_first_letter( area_name );
6587  area = e->string_id;
6588  }
6589  mvwprintz( w_look, point( column, line++ ), c_yellow, area );
6590  mvwprintz( w_look, point( column, line++ ), c_white, tile );
6591  std::string desc = string_format( m.ter( lp ).obj().description );
6592  std::vector<std::string> lines = foldstring( desc, max_width );
6593  int numlines = lines.size();
6594  for( int i = 0; i < numlines; i++ ) {
6595  mvwprintz( w_look, point( column, line++ ), c_light_gray, lines[i] );
6596  }
6597 
6598  // Furniture, if any
6599  print_furniture_info( lp, w_look, column, line );
6600 
6601  // Cover percentage from terrain and furniture next.
6602  fold_and_print( w_look, point( column, ++line ), max_width, c_light_gray, _( "Concealment: %d%%" ),
6603  m.coverage( lp ) );
6604 
6605  if( m.has_flag( ter_furn_flag::TFLAG_TREE, lp ) ) {
6606  const int lines = fold_and_print( w_look, point( column, ++line ), max_width, c_light_gray,
6607  _( "Can be <color_green>cut down</color> with the right tools." ) );
6608  line += lines - 1;
6609  }
6610 
6611  // Terrain and furniture flags next. These can be several lines for some combinations of
6612  // furnitures and terrains.
6613  lines = foldstring( m.features( lp ), max_width );
6614  numlines = lines.size();
6615  for( int i = 0; i < numlines; i++ ) {
6616  mvwprintz( w_look, point( column, ++line ), c_light_gray, lines[i] );
6617  }
6618 
6619  // Move cost from terrain and furniture and vehicle parts.
6620  // Vehicle part information is printed in a different function.
6621  if( m.impassable( lp ) ) {
6622  mvwprintz( w_look, point( column, ++line ), c_light_red, _( "Impassable" ) );
6623  } else {
6624  mvwprintz( w_look, point( column, ++line ), c_light_gray, _( "Move cost: %d" ),
6625  m.move_cost( lp ) * 50 );
6626  }
6627 
6628  // Next print the string on any SIGN flagged furniture if any.
6629  std::string signage = m.get_signage( lp );
6630  if( !signage.empty() ) {
6631  std::string sign_string = u.has_trait( trait_ILLITERATE ) ? "???" : signage;
6632  const int lines = fold_and_print( w_look, point( column, ++line ), max_width, c_light_gray,
6633  _( "Sign: %s" ), sign_string );
6634  line += lines - 1;
6635  }
6636 
6637  // Print light level on the selected tile.
6638  std::pair<std::string, nc_color> ll = get_light_level( std::max( 1.0,
6639  LIGHT_AMBIENT_LIT - m.ambient_light_at( lp ) + 1.0 ) );
6640  mvwprintz( w_look, point( column, ++line ), c_light_gray, _( "Lighting: " ) );
6641  mvwprintz( w_look, point( column + utf8_width( _( "Lighting: " ) ), line ), ll.second, ll.first );
6642 
6643  // Print the terrain and any furntiure on the tile below and whether it is walkable.
6644  if( lp.z > -OVERMAP_DEPTH && !m.has_floor( lp ) ) {
6645  tripoint below( lp.xy(), lp.z - 1 );
6646  std::string tile_below = m.tername( below );
6647  if( m.has_furn( below ) ) {
6648  tile_below += ", " + m.furnname( below );
6649  }
6650 
6651  if( !m.has_floor_or_support( lp ) ) {
6652  fold_and_print( w_look, point( column, ++line ), max_width, c_dark_gray,
6653  _( "Below: %s; No support" ), tile_below );
6654  } else {
6655  fold_and_print( w_look, point( column, ++line ), max_width, c_dark_gray, _( "Below: %s; Walkable" ),
6656  tile_below );
6657  }
6658  }
6659 
6660  ++line;
6661 }
void print_furniture_info(const tripoint &lp, const catacurses::window &w_look, int column, int &line)
Definition: game.cpp:6663
std::string features(const tripoint &p) const
Definition: map.cpp:2345
bool has_floor_or_support(const tripoint &p) const
Definition: map.cpp:2733
float ambient_light_at(const tripoint &p) const
Definition: lightmap.cpp:640
int coverage(const tripoint &p) const
Returns coverage value of the tile.
Definition: map.cpp:7599
bool has_floor(const tripoint &p) const
Definition: map.cpp:2691
constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
std::pair< std::string, nc_color > get_light_level(const float light)
Definition: output.cpp:2674

References _, map::ambient_light_at(), below, c_dark_gray, c_light_gray, c_light_red, c_white, c_yellow, map::coverage(), map_data_common_t::description, map::features(), fold_and_print(), foldstring(), map::furnname(), rotatable_symbols::get(), get_light_level(), map::get_signage(), get_timed_events, catacurses::getmaxx(), map::has_flag(), map::has_floor(), map::has_floor_or_support(), map::has_furn(), Character::has_trait(), map::impassable(), LIGHT_AMBIENT_LIT, line, m, max(), map::move_cost(), mvwprintz(), int_id< T >::obj(), OVERMAP_DEPTH, OVERRIDE_PLACE, point, print_furniture_info(), string_format(), map::ter(), map::tername(), TFLAG_TREE, trait_ILLITERATE, u, uppercase_first_letter(), utf8_width(), tripoint::xy(), and tripoint::z.

Referenced by print_all_tile_info().

◆ print_trap_info()

void game::print_trap_info ( const tripoint lp,
const catacurses::window w_look,
int  column,
int &  line 
)
private

Definition at line 6729 of file game.cpp.

6731 {
6732  const trap &tr = m.tr_at( lp );
6733  if( tr.can_see( lp, u ) ) {
6734  std::string tr_name = tr.name();
6735  mvwprintz( w_look, point( column, ++line ), tr.color, tr_name );
6736  }
6737 
6738  ++line;
6739 }
nc_color color
Definition: trap.h:117

References trap::can_see(), trap::color, line, m, mvwprintz(), trap::name(), point, map::tr_at(), and u.

Referenced by print_all_tile_info().

◆ print_vehicle_info()

void game::print_vehicle_info ( const vehicle veh,
int  veh_part,
const catacurses::window w_look,
int  column,
int &  line,
int  last_line 
)
private

Definition at line 6769 of file game.cpp.

6771 {
6772  if( veh ) {
6773  // Print the name of the vehicle.
6774  mvwprintz( w_look, point( column, ++line ), c_light_gray, _( "Vehicle: " ) );
6775  mvwprintz( w_look, point( column + utf8_width( _( "Vehicle: " ) ), line ), c_white, "%s",
6776  veh->name );
6777  // Then the list of parts on that tile.
6778  line = veh->print_part_list( w_look, ++line, last_line, getmaxx( w_look ), veh_part );
6779  }
6780 }
int print_part_list(const catacurses::window &win, int y1, int max_y, int width, int p, int hl=-1, bool detail=false, bool include_fakes=true) const
Prints a list of all parts to the screen inside of a boxed window, possibly highlighting a selected o...

References _, c_light_gray, c_white, catacurses::getmaxx(), line, mvwprintz(), vehicle::name, point, vehicle::print_part_list(), and utf8_width().

Referenced by print_all_tile_info().

◆ print_visibility_info()

void game::print_visibility_info ( const catacurses::window w_look,
int  column,
int &  line,
visibility_type  visibility 
)
private

Definition at line 6548 of file game.cpp.

6550 {
6551  const char *visibility_message = nullptr;
6552  switch( visibility ) {
6554  visibility_message = _( "Clearly visible." );
6555  break;
6557  visibility_message = _( "A bright pink blur." );
6558  break;
6560  visibility_message = _( "A pink blur." );
6561  break;
6562  case visibility_type::DARK:
6563  visibility_message = _( "Darkness." );
6564  break;
6565  case visibility_type::LIT:
6566  visibility_message = _( "Bright light." );
6567  break;
6569  visibility_message = _( "Unseen." );
6570  break;
6571  }
6572 
6573  mvwprintz( w_look, point( line, column ), c_light_gray, visibility_message );
6574  line += 2;
6575 }

References _, BOOMER, BOOMER_DARK, c_light_gray, CLEAR, DARK, HIDDEN, line, LIT, mvwprintz(), and point.

Referenced by print_all_tile_info().

◆ prompt_dangerous_tile()

bool game::prompt_dangerous_tile ( const tripoint dest_loc) const

Definition at line 10413 of file game.cpp.

10414 {
10416  return true;
10417  }
10418 
10419  std::vector<std::string> harmful_stuff = get_dangerous_tile( dest_loc );
10420 
10421  if( !harmful_stuff.empty() &&
10422  !query_yn( _( "Really step into %s?" ), enumerate_as_string( harmful_stuff ) ) ) {
10423  return false;
10424  }
10425  if( !harmful_stuff.empty() && u.is_mounted() && m.tr_at( dest_loc ) == tr_ledge ) {
10426  add_msg( m_warning, _( "Your %s refuses to move over that ledge!" ),
10427  u.mounted_creature->get_name() );
10428  return false;
10429  }
10430  return true;
10431 }
static const efftype_id effect_psi_stunned("psi_stunned")

References _, add_msg(), effect_psi_stunned, effect_stunned, enumerate_as_string(), get_dangerous_tile(), Creature::has_effect(), Character::is_mounted(), m, m_warning, Character::mounted_creature, query_yn(), map::tr_at(), tr_ledge, and u.

Referenced by npc_menu(), and walk_move().

◆ quickload()

void game::quickload ( )

Definition at line 13066 of file game.cpp.

13067 {
13068  const WORLD *active_world = world_generator->active_world;
13069  if( active_world == nullptr ) {
13070  return;
13071  }
13072  std::string const world_name = active_world->world_name;
13073  std::string const &save_id = u.get_save_id();
13074 
13075  if( active_world->save_exists( save_t::from_save_id( save_id ) ) ) {
13076  if( moves_since_last_save != 0 ) { // See if we need to reload anything
13078  last_save_timestamp = std::time( nullptr );
13079 
13080  u.set_moves( 0 );
13081  uquit = QUIT_NOSAVED;
13082 
13083  main_menu::queued_world_to_load = world_name;
13085 
13086  }
13087 
13088  } else {
13089  popup_getkey( _( "No saves for current character yet." ) );
13090  }
13091 }
static std::string queued_save_id_to_load
Definition: main_menu.h:23
static std::string queued_world_to_load
Definition: main_menu.h:22
static save_t from_save_id(const std::string &save_id)
@ QUIT_NOSAVED
Definition: game.h:56
int popup_getkey(const char *const mes, Args &&... args)
Definition: output.h:482
std::string world_name
Definition: worldfactory.h:62
bool save_exists(const save_t &name) const

References _, save_t::from_save_id(), avatar::get_save_id(), last_save_timestamp, moves_since_last_save, popup_getkey(), main_menu::queued_save_id_to_load, main_menu::queued_world_to_load, QUIT_NOSAVED, WORLD::save_exists(), Creature::set_moves(), u, uquit, world_generator, and WORLD::world_name.

Referenced by do_regular_action().

◆ quicksave()

void game::quicksave ( )

Definition at line 13044 of file game.cpp.

13045 {
13046  //Don't autosave if the player hasn't done anything since the last autosave/quicksave,
13047  if( !moves_since_last_save ) {
13048  return;
13049  }
13050  add_msg( m_info, _( "Saving game, this may take a while." ) );
13051 
13053  popup.message( "%s", _( "Saving game, this may take a while." ) );
13055  refresh_display();
13056 
13057  time_t now = std::time( nullptr ); //timestamp for start of saving procedure
13058 
13059  //perform save
13060  save();
13061  //Now reset counters for autosaving, so we don't immediately autosave after a quicksave or autosave.
13063  last_save_timestamp = now;
13064 }

References _, add_msg(), last_save_timestamp, m_info, moves_since_last_save, popup(), ui_manager::redraw(), refresh_display(), and save().

Referenced by autosave(), and do_regular_action().

◆ reenter_fullscreen()

void game::reenter_fullscreen ( )

Definition at line 752 of file game.cpp.

753 {
754  if( was_fullscreen ) {
755  if( !fullscreen ) {
757  }
758  }
759 }

References fullscreen, toggle_fullscreen(), and was_fullscreen.

Referenced by look_around().

◆ reload()

void game::reload ( item_location loc,
bool  prompt = false,
bool  empty = true 
)
private

Definition at line 9936 of file game.cpp.

9937 {
9938  // bows etc. do not need to reload. select favorite ammo for them instead
9939  if( loc->has_flag( flag_RELOAD_AND_SHOOT ) ) {
9940  item::reload_option opt = u.select_ammo( loc, prompt );
9941  if( !opt ) {
9942  return;
9943  } else if( u.ammo_location && opt.ammo == u.ammo_location ) {
9944  u.add_msg_if_player( _( "Cleared ammo preferences for %s." ), loc->tname() );
9946  } else if( u.has_item( *opt.ammo ) ) {
9947  u.add_msg_if_player( _( "Selected %s as default ammo for %s." ), opt.ammo->tname(), loc->tname() );
9948  u.ammo_location = opt.ammo;
9949  } else {
9950  u.add_msg_if_player( _( "You need to keep that ammo on you to select it as default ammo." ) );
9951  }
9952  return;
9953  }
9954 
9955  switch( u.rate_action_reload( *loc ) ) {
9956  case hint_rating::iffy:
9957  if( ( loc->is_ammo_container() || loc->is_magazine() ) && loc->ammo_remaining() > 0 &&
9958  loc->remaining_ammo_capacity() == 0 ) {
9959  add_msg( m_info, _( "The %s is already fully loaded!" ), loc->tname() );
9960  return;
9961  }
9962  if( loc->is_ammo_belt() ) {
9963  const auto &linkage = loc->type->magazine->linkage;
9964  if( linkage && !u.has_charges( *linkage, 1 ) ) {
9965  add_msg( m_info, _( "You need at least one %s to reload the %s!" ),
9966  item::nname( *linkage, 1 ), loc->tname() );
9967  return;
9968  }
9969  }
9970  if( loc->is_watertight_container() && loc->is_container_full() ) {
9971  add_msg( m_info, _( "The %s is already full!" ), loc->tname() );
9972  return;
9973  }
9974 
9975  // intentional fall-through
9976 
9977  case hint_rating::cant:
9978  add_msg( m_info, _( "You can't reload a %s!" ), loc->tname() );
9979  return;
9980 
9981  case hint_rating::good:
9982  break;
9983  }
9984 
9985  if( !u.has_item( *loc ) && !loc->has_flag( flag_ALLOWS_REMOTE_USE ) ) {
9986  loc = loc.obtain( u );
9987  if( !loc ) {
9988  add_msg( _( "Never mind." ) );
9989  return;
9990  }
9991  }
9992 
9993  // for holsters and ammo pouches try to reload any contained item
9994  if( loc->type->can_use( "holster" ) && loc->num_item_stacks() == 1 ) {
9995  loc = item_location( loc, &loc->only_item() );
9996  }
9997 
9998  item::reload_option opt = favorite_ammo_or_select( u, loc, empty, prompt );
9999 
10000  if( opt.ammo.get_item() == nullptr || ( opt.ammo.get_item()->is_frozen_liquid() &&
10001  !u.crush_frozen_liquid( opt.ammo ) ) ) {
10002  return;
10003  }
10004 
10005  if( opt ) {
10006  const int extra_moves = loc->get_var( "dirt", 0 ) > 7800 ? 2500 : 0;
10007  if( extra_moves > 0 ) {
10008  add_msg( m_warning, _( "You struggle to reload the fouled %s." ), loc->tname() );
10009  }
10010  u.assign_activity( reload_activity_actor( std::move( opt ), extra_moves ) );
10011  }
10012 }
bool crush_frozen_liquid(item_location loc)
Prompts user about crushing item at item_location loc, for harvesting of frozen liquids.
bool has_charges(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const override
Definition: character.cpp:9586
item_location obtain(Character &ch, int qty=-1)
Move an item from the location to the character inventory If the player fails to obtain the item (lik...
double get_var(const std::string &name, double default_value) const
Definition: item.cpp:1839
bool is_ammo_container() const
Definition: item.cpp:9578
bool is_watertight_container() const
Whether this is a container which can be used to store liquids.
Definition: item.cpp:9741
int ammo_remaining(const Character *carrier=nullptr, bool include_linked=false) const
Quantity of ammunition currently loaded in tool, gun or auxiliary gunmod.
Definition: item.cpp:10739
static std::string nname(const itype_id &id, unsigned int quantity=1)
Returns the translated item name for the item with given id.
Definition: item.cpp:14557
bool is_ammo_belt() const
Definition: item.cpp:9460
bool is_frozen_liquid() const
Returns true if the item is A: is SOLID and if it B: is of type LIQUID.
Definition: item.cpp:937
bool is_container_full(bool allow_bucket=false) const
Whether this item has no more free capacity for its current content.
Definition: item.cpp:9858
int remaining_ammo_capacity() const
how much more ammo can fit into this item if this item is not loaded, gives remaining capacity of its...
Definition: item.cpp:10787
bool is_magazine() const
Definition: item.cpp:9445
item & only_item()
Definition: item.cpp:15145
const flag_id flag_ALLOWS_REMOTE_USE("ALLOWS_REMOTE_USE")
static item::reload_option favorite_ammo_or_select(avatar &u, item_location &loc, bool empty, bool prompt)
Definition: game.cpp:9916
@ prompt
Definition: pickup.h:42
cata::value_ptr< islot_magazine > magazine
Definition: itype.h:1209
bool can_use(const std::string &iuse_name) const
Definition: itype.cpp:174

References _, add_msg(), Character::add_msg_if_player(), item::reload_option::ammo, Character::ammo_location, item::ammo_remaining(), Character::assign_activity(), itype::can_use(), cant, Character::crush_frozen_liquid(), favorite_ammo_or_select(), flag_ALLOWS_REMOTE_USE, flag_RELOAD_AND_SHOOT, item_location::get_item(), item::get_var(), good, Character::has_charges(), item::has_flag(), visitable::has_item(), iffy, item::is_ammo_belt(), item::is_ammo_container(), item::is_container_full(), item::is_frozen_liquid(), item::is_magazine(), item::is_watertight_container(), m_info, m_warning, itype::magazine, item::nname(), item::num_item_stacks(), item_location::obtain(), item::only_item(), Pickup::prompt, Character::rate_action_reload(), item::remaining_ammo_capacity(), avatar::select_ammo(), item::tname(), item::type, and u.

Referenced by inventory_item_menu(), reload_item(), and reload_wielded().

◆ reload_item()

void game::reload_item ( )

Definition at line 10015 of file game.cpp.

10016 {
10017  item_location item_loc = inv_map_splice( [&]( const item & it ) {
10018  return u.rate_action_reload( it ) == hint_rating::good;
10019  }, _( "Reload item" ), 1, _( "You have nothing to reload." ) );
10020 
10021  if( !item_loc ) {
10022  add_msg( _( "Never mind." ) );
10023  return;
10024  }
10025 
10026  reload( item_loc );
10027 }

References _, add_msg(), good, inv_map_splice(), Character::rate_action_reload(), reload(), and u.

Referenced by do_regular_action().

◆ reload_npcs()

void game::reload_npcs ( )

Unloads, then loads the NPCs.

Definition at line 1264 of file game.cpp.

1265 {
1266  // TODO: Make it not invoke the "on_unload" command for the NPCs that will be loaded anyway
1267  // and not invoke "on_load" for those NPCs that avoided unloading this way.
1268  unload_npcs();
1269  load_npcs();
1270 }

References load_npcs(), and unload_npcs().

Referenced by load().

◆ reload_tileset()

void game::reload_tileset ( )

Definition at line 697 of file game.cpp.

698 {
699 #if defined(TILES)
700  // Disable UIs below to avoid accessing the tile context during loading.
702  try {
703  closetilecontext->reinit();
704  closetilecontext->load_tileset( get_option<std::string>( "TILES" ),
705  /*precheck=*/false, /*force=*/true,
706  /*pump_events=*/true );
707  closetilecontext->do_tile_loading_report();
708 
709  tilecontext = closetilecontext;
710  } catch( const std::exception &err ) {
711  popup( _( "Loading the tileset failed: %s" ), err.what() );
712  }
713  if( use_far_tiles ) {
714  try {
715  if( fartilecontext->is_valid() ) {
716  fartilecontext->reinit();
717  }
718  fartilecontext->load_tileset( get_option<std::string>( "DISTANT_TILES" ),
719  /*precheck=*/false, /*force=*/true,
720  /*pump_events=*/true );
721  fartilecontext->do_tile_loading_report();
722  } catch( const std::exception &err ) {
723  popup( _( "Loading the zoomed out tileset failed: %s" ), err.what() );
724  }
725  }
726  try {
727  overmap_tilecontext->reinit();
728  overmap_tilecontext->load_tileset( get_option<std::string>( "OVERMAP_TILES" ),
729  /*precheck=*/false, /*force=*/true,
730  /*pump_events=*/true );
731  overmap_tilecontext->do_tile_loading_report();
732  } catch( const std::exception &err ) {
733  popup( _( "Loading the overmap tileset failed: %s" ), err.what() );
734  }
735  g->reset_zoom();
736  g->mark_main_ui_adaptor_resize();
737 #endif // TILES
738 }
bool use_far_tiles

References _, g, popup(), and use_far_tiles.

Referenced by do_regular_action().

◆ reload_weapon()

void game::reload_weapon ( bool  try_everything = true)

Definition at line 10039 of file game.cpp.

10040 {
10041  // As a special streamlined activity, hitting reload repeatedly should:
10042  // Reload wielded gun
10043  // First reload a magazine if necessary.
10044  // Then load said magazine into gun.
10045  // Reload magazines that are compatible with the current gun.
10046  // Reload other guns in inventory.
10047  // Reload misc magazines in inventory.
10048  std::vector<item_location> reloadables = u.find_reloadables();
10049  std::sort( reloadables.begin(), reloadables.end(),
10050  [this]( const item_location & a, const item_location & b ) {
10051  // Non gun/magazines are sorted last and later ignored.
10052  if( !a->is_magazine() && !a->is_gun() ) {
10053  return false;
10054  }
10055  // Current wielded weapon comes first.
10056  if( this->u.is_wielding( *b ) ) {
10057  return false;
10058  }
10059  if( this->u.is_wielding( *a ) ) {
10060  return true;
10061  }
10062  // Second sort by affiliation with wielded gun
10063  item_location weapon = u.get_wielded_item();
10064  if( weapon ) {
10065  const bool mag_a = weapon->is_compatible( *a ).success();
10066  const bool mag_b = weapon->is_compatible( *b ).success();
10067  if( mag_a != mag_b ) {
10068  return mag_a;
10069  }
10070  }
10071  // Third sort by gun vs magazine,
10072  if( a->is_gun() != b->is_gun() ) {
10073  return a->is_gun();
10074  }
10075  // Finally sort by speed to reload.
10076  return ( a->get_reload_time() * a->remaining_ammo_capacity() ) <
10077  ( b->get_reload_time() * b->remaining_ammo_capacity() );
10078  } );
10079  for( item_location &candidate : reloadables ) {
10080  if( !candidate->is_magazine() && !candidate->is_gun() ) {
10081  continue;
10082  }
10083  std::vector<item::reload_option> ammo_list;
10084  u.list_ammo( candidate, ammo_list, false );
10085  if( !ammo_list.empty() ) {
10086  reload( candidate, false, false );
10087  return;
10088  }
10089  }
10090  // Just for testing, bail out here to avoid unwanted side effects.
10091  if( !try_everything ) {
10092  return;
10093  }
10094  // If we make it here and haven't found anything to reload, start looking elsewhere.
10095  const optional_vpart_position ovp = m.veh_at( u.pos() );
10096  if( ovp ) {
10097  const turret_data turret = ovp->vehicle().turret_query( ovp->pos() );
10098  if( turret.can_reload() ) {
10099  item::reload_option opt = u.select_ammo( turret.base(), true );
10100  if( opt ) {
10101  u.assign_activity( reload_activity_actor( std::move( opt ) ) );
10102  }
10103  }
10104  return;
10105  }
10106 
10107  reload_item();
10108 }
bool list_ammo(const item_location &base, std::vector< item::reload_option > &ammo_list, bool empty=true) const
std::vector< item_location > find_reloadables()
Searches for weapons and magazines that can be reloaded.
bool can_reload() const
Definition: turret.cpp:212
item_location base()
Get base item location.
Definition: turret.cpp:79

References a, b, Character::find_reloadables(), Character::get_wielded_item(), and u.

Referenced by do_regular_action().

◆ reload_wielded()

void game::reload_wielded ( bool  prompt = false)

Definition at line 10029 of file game.cpp.

10030 {
10031  item_location weapon = u.get_wielded_item();
10032  if( !weapon || !weapon->is_reloadable() ) {
10033  add_msg( _( "You aren't holding something you can reload." ) );
10034  return;
10035  }
10036  reload( weapon, prompt );
10037 }
bool is_reloadable() const
Is it ever possible to reload this item? ALso checks for reloading installed gunmods.
Definition: item.cpp:14413

References _, add_msg(), Character::get_wielded_item(), item::is_reloadable(), Pickup::prompt, reload(), and u.

Referenced by do_regular_action().

◆ remoteveh()

vehicle * game::remoteveh ( )

Returns the current remotely controlled vehicle.

Definition at line 2611 of file game.cpp.

2612 {
2614  return remoteveh_cache;
2615  }
2617  std::stringstream remote_veh_string( u.get_value( "remote_controlling_vehicle" ) );
2618  if( remote_veh_string.str().empty() ||
2620  remoteveh_cache = nullptr;
2621  } else {
2622  tripoint vp;
2623  remote_veh_string >> vp.x >> vp.y >> vp.z;
2624  vehicle *veh = veh_pointer_or_null( m.veh_at( vp ) );
2625  if( veh && veh->fuel_left( itype_battery ) > 0 ) {
2626  remoteveh_cache = veh;
2627  } else {
2628  remoteveh_cache = nullptr;
2629  }
2630  }
2631  return remoteveh_cache;
2632 }
vehicle * remoteveh_cache
Definition: game.h:1180
int64_t fuel_left(const itype_id &ftype, const std::function< bool(const vehicle_part &)> &filter=return_true< const vehicle_part & >) const
Definition: vehicle.cpp:3516
static const bionic_id bio_remote("bio_remote")
static const itype_id itype_remotevehcontrol("remotevehcontrol")
static const itype_id itype_battery("battery")

References bio_remote, vehicle::fuel_left(), Creature::get_value(), Character::has_active_bionic(), Character::has_active_item(), itype_battery, itype_remotevehcontrol, m, remoteveh_cache, remoteveh_cache_time, calendar::turn, u, map::veh_at(), veh_pointer_or_null(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by control_vehicle().

◆ remove_npc()

void game::remove_npc ( character_id const &  id)

Definition at line 1252 of file game.cpp.

1253 {
1254  std::list<shared_ptr_fast<npc>> &active_npc = critter_tracker->active_npc;
1255  auto const it = std::find_if( active_npc.begin(), active_npc.end(),
1256  [id]( shared_ptr_fast<npc> const & n ) {
1257  return n->getID() == id;
1258  } );
1259  if( it != active_npc.end() ) {
1260  active_npc.erase( it );
1261  }
1262 }

References critter_tracker.

◆ remove_npc_follower()

void game::remove_npc_follower ( const character_id id)

Remove follower id from follower set.

Definition at line 1731 of file game.cpp.

1732 {
1733  follower_ids.erase( id );
1734  u.follower_ids.erase( id );
1735 }

References avatar::follower_ids, follower_ids, and u.

Referenced by cleanup_dead().

◆ remove_zombie()

void game::remove_zombie ( const monster critter)

Definition at line 5285 of file game.cpp.

5286 {
5287  critter_tracker->remove( critter );
5288 }

References critter_tracker.

Referenced by despawn_monster(), and start_game().

◆ reset_item_list_state()

void game::reset_item_list_state ( const catacurses::window window,
int  height,
bool  bRadiusSort 
)
private

Definition at line 8278 of file game.cpp.

8279 {
8280  const int width = getmaxx( window );
8281  for( int i = 1; i < TERMX; i++ ) {
8282  if( i < width ) {
8283  mvwputch( window, point( i, 0 ), c_light_gray, LINE_OXOX ); // -
8284  mvwputch( window, point( i, TERMY - height - 1 ), c_light_gray,
8285  LINE_OXOX ); // -
8286  }
8287 
8288  if( i < TERMY - height ) {
8289  mvwputch( window, point( 0, i ), c_light_gray, LINE_XOXO ); // |
8290  mvwputch( window, point( width - 1, i ), c_light_gray, LINE_XOXO ); // |
8291  }
8292  }
8293 
8294  mvwputch( window, point_zero, c_light_gray, LINE_OXXO ); // |^
8295  mvwputch( window, point( width - 1, 0 ), c_light_gray, LINE_OOXX ); // ^|
8296 
8297  mvwputch( window, point( 0, TERMY - height - 1 ), c_light_gray,
8298  LINE_XXXO ); // |-
8299  mvwputch( window, point( width - 1, TERMY - height - 1 ), c_light_gray,
8300  LINE_XOXX ); // -|
8301 
8302  mvwprintz( window, point( 2, 0 ), c_light_green, "<Tab> " );
8303  wprintz( window, c_white, _( "Items" ) );
8304 
8305  std::string sSort;
8306  if( bRadiusSort ) {
8307  //~ Sort type: distance.
8308  sSort = _( "<s>ort: dist" );
8309  } else {
8310  //~ Sort type: category.
8311  sSort = _( "<s>ort: cat" );
8312  }
8313 
8314  int letters = utf8_width( sSort );
8315 
8316  shortcut_print( window, point( getmaxx( window ) - letters, 0 ), c_white, c_light_green, sSort );
8317 
8318  std::vector<std::string> tokens;
8319  if( !sFilter.empty() ) {
8320  tokens.emplace_back( _( "<R>eset" ) );
8321  }
8322 
8323  tokens.emplace_back( _( "<E>xamine" ) );
8324  tokens.emplace_back( _( "<C>ompare" ) );
8325  tokens.emplace_back( _( "<F>ilter" ) );
8326  tokens.emplace_back( _( "<+/->Priority" ) );
8327  tokens.emplace_back( _( "<T>ravel to" ) );
8328 
8329  int gaps = tokens.size() + 1;
8330  letters = 0;
8331  int n = tokens.size();
8332  for( int i = 0; i < n; i++ ) {
8333  letters += utf8_width( tokens[i] ) - 2; //length ignores < >
8334  }
8335 
8336  int usedwidth = letters;
8337  const int gap_spaces = ( width - usedwidth ) / gaps;
8338  usedwidth += gap_spaces * gaps;
8339  point pos( gap_spaces + ( width - usedwidth ) / 2, TERMY - height - 1 );
8340 
8341  for( int i = 0; i < n; i++ ) {
8342  pos.x += shortcut_print( window, pos, c_white, c_light_green,
8343  tokens[i] ) + gap_spaces;
8344  }
8345 }
#define LINE_OOXX
Definition: output.h:50
#define LINE_OXXO
Definition: output.h:49

References _, c_light_gray, c_light_green, c_white, catacurses::getmaxx(), LINE_OOXX, LINE_OXOX, LINE_OXXO, LINE_XOXO, LINE_XOXX, LINE_XXXO, mvwprintz(), mvwputch(), point, point_zero, math_opers::pos(), sFilter, shortcut_print(), TERMX, TERMY, utf8_width(), and wprintz().

Referenced by list_items().

◆ reset_light_level()

void game::reset_light_level ( )

Definition at line 4458 of file game.cpp.

4459 {
4460  for( float &lev : latest_lightlevels ) {
4462  }
4463 }

References latest_lightlevels, and max().

Referenced by game().

◆ reset_npc_dispositions()

void game::reset_npc_dispositions ( )
private

Definition at line 3305 of file game.cpp.

3306 {
3307  for( character_id elem : follower_ids ) {
3308  shared_ptr_fast<npc> npc_to_get = overmap_buffer.find_npc( elem );
3309  if( !npc_to_get ) {
3310  continue;
3311  }
3312  npc *npc_to_add = npc_to_get.get();
3313  npc_to_add->chatbin.clear_all();
3314  npc_to_add->mission = NPC_MISSION_NULL;
3315  npc_to_add->set_attitude( NPCATT_NULL );
3316  npc_to_add->op_of_u = npc_opinion();
3317  npc_to_add->set_fac( faction_no_faction );
3319  npc_to_add->global_omt_location(),
3320  npc_to_add->getID() ) );
3321 
3322  }
3323 
3324 }
void set_attitude(npc_attitude new_attitude)
Definition: npc.cpp:3551
dialogue_chatbin chatbin
Definition: npc.h:1406
void add_new_mission(mission *miss)
See dialogue_chatbin::add_new_mission.
Definition: npc.cpp:3052
void set_fac(const faction_id &id)
Definition: npc.cpp:747

References npc::add_new_mission(), npc::chatbin, dialogue_chatbin::clear_all(), faction_no_faction, overmapbuffer::find_npc(), follower_ids, Character::getID(), Creature::global_omt_location(), npc::mission, NPC_MISSION_NULL, NPCATT_NULL, npc::op_of_u, ORIGIN_ANY_NPC, overmap_buffer, mission::reserve_random(), npc::set_attitude(), and npc::set_fac().

◆ reset_zoom()

void game::reset_zoom ( )

Definition at line 8195 of file game.cpp.

8196 {
8197 #if defined(TILES)
8199  rescale_tileset( tileset_zoom );
8200 #endif // TILES
8201 }

References DEFAULT_TILESET_ZOOM, and tileset_zoom.

◆ revive_corpse() [1/2]

bool game::revive_corpse ( const tripoint p,
item it 
)

Revives a corpse at given location.

The monster type and some of its properties are deducted from the corpse. If reviving succeeds, the location is guaranteed to have a new monster there (see creature_at).

Parameters
pThe place where to put the revived monster.
itThe corpse item, it must be a valid corpse (see item::is_corpse).
Returns
Whether the corpse has actually been redivided. Reviving may fail for many reasons, including no space to put the monster, corpse being to much damaged etc. If the monster was revived, the caller should remove the corpse item. If reviving failed, the item is unchanged, as is the environment (no new monsters).

Definition at line 5533 of file game.cpp.

5534 {
5535  return revive_corpse( p, it, 1 );
5536 }
bool revive_corpse(const tripoint &p, item &it)
Revives a corpse at given location.
Definition: game.cpp:5533

◆ revive_corpse() [2/2]

bool game::revive_corpse ( const tripoint p,
item it,
int  radius 
)

Definition at line 5538 of file game.cpp.

5539 {
5540  if( !it.is_corpse() ) {
5541  debugmsg( "Tried to revive a non-corpse." );
5542  return false;
5543  }
5544  // If this is not here, the game may attempt to spawn a monster before the map exists,
5545  // leading to it querying for furniture, and crashing.
5546  if( g->new_game ) {
5547  return false;
5548  }
5550  it.has_flag( flag_QUARTERED ) ) {
5551  // Failed reanimation due to corpse being butchered
5552  return false;
5553  }
5554  shared_ptr_fast<monster> newmon_ptr;
5555  if( it.has_var( "zombie_form" ) ) {
5556  // the monster was not a zombie but turns into one when its corpse is revived
5557  newmon_ptr = make_shared_fast<monster>( mtype_id( it.get_var( "zombie_form" ) ) );
5558  } else {
5559  newmon_ptr = make_shared_fast<monster>( it.get_mtype()->id );
5560  }
5561  monster &critter = *newmon_ptr;
5562  critter.init_from_item( it );
5563  if( critter.get_hp() < 1 ) {
5564  // Failed reanimation due to corpse being too burned
5565  return false;
5566  }
5567 
5568  critter.no_extra_death_drops = true;
5569  critter.add_effect( effect_downed, 5_turns, true );
5570 
5571  if( it.get_var( "no_ammo" ) == "no_ammo" ) {
5572  for( auto &ammo : critter.ammo ) {
5573  ammo.second = 0;
5574  }
5575  }
5576 
5577  return place_critter_around( newmon_ptr, p, radius );
5578 }
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1928
const mtype * get_mtype() const
Definition: item.cpp:9531
int get_hp(const bodypart_id &) const override
Definition: monster.cpp:3743
bool no_extra_death_drops
Definition: monster.h:552
std::map< itype_id, int > ammo
Definition: monster.h:582
void init_from_item(item &itm)
Initialize values like speed / hp from data of an item.
Definition: monster.cpp:3590
const flag_id flag_FIELD_DRESS_FAILED("FIELD_DRESS_FAILED")
const flag_id flag_QUARTERED("QUARTERED")
const flag_id flag_FIELD_DRESS("FIELD_DRESS")
static const efftype_id effect_downed("downed")

References Creature::add_effect(), monster::ammo, debugmsg, effect_downed, flag_FIELD_DRESS, flag_FIELD_DRESS_FAILED, flag_QUARTERED, g, monster::get_hp(), item::get_mtype(), item::get_var(), item::has_flag(), item::has_var(), mtype::id, monster::init_from_item(), item::is_corpse(), mtype_id, monster::no_extra_death_drops, and place_critter_around().

◆ safe_route_to()

std::optional< std::vector< tripoint_bub_ms > > game::safe_route_to ( Character who,
const tripoint_bub_ms target,
int  threshold,
const std::function< void(const std::string &msg)> &  report 
) const

attempt to find a safe route (avoids tiles dangerous to 'who').

Parameters
whocharacter to use for evaluating danger tiles and pathfinding start position
targetpathfinding destination tile
thresholddistance in tiles from target that is considered "arrived" at destination
reportwhen pathfinding fails triggers this function with a translated error string as parameter
Returns
safe route if one was found, or std::nullopt

Definition at line 7588 of file game.cpp.

7591 {
7592  map &here = get_map();
7593  if( !who.sees( target ) ) {
7594  report( _( "You can't see the destination." ) );
7595  return std::nullopt;
7596  }
7597  if( rl_dist( who.pos_bub(), target ) <= threshold ) {
7598  return {}; // no need to move anywhere, already near destination
7599  }
7600  using route_t = std::vector<tripoint_bub_ms>;
7601  const auto get_shorter_route = [&who]( const route_t &a, const route_t &b ) {
7602  if( a.empty() ) {
7603  return b; // if route is empty return the non-empty one
7604  } else if( b.empty() ) {
7605  return a; // if route is empty return the non-empty one
7606  } else if( a.size() != b.size() ) {
7607  return a.size() < b.size() ? a : b; // if both non empty return shortest length in tiles
7608  } else {
7609  // if both are equal length in tiles return the one closest to target
7610  const float dist_a = rl_dist_exact( who.pos_bub().raw(), a.back().raw() );
7611  const float dist_b = rl_dist_exact( who.pos_bub().raw(), b.back().raw() );
7612  return dist_a < dist_b ? a : b;
7613  }
7614  };
7615  route_t shortest_route;
7616  std::unordered_set<tripoint> path_avoid;
7617  for( const tripoint_bub_ms &p : points_in_radius( who.pos_bub(), 60 ) ) {
7618  if( is_dangerous_tile( p.raw() ) ) {
7619  path_avoid.insert( p.raw() );
7620  }
7621  }
7622  for( const tripoint_bub_ms &p : here.points_in_radius( target, threshold, 0 ) ) {
7623  if( path_avoid.count( p.raw() ) > 0 ) {
7624  continue; // dont route to dangerous tiles
7625  }
7626  const route_t route = here.route( who.pos_bub(), p, who.get_pathfinding_settings(), path_avoid );
7627  if( route.empty() ) {
7628  continue; // no route
7629  }
7630  shortest_route = get_shorter_route( shortest_route, route );
7631  }
7632  if( shortest_route.empty() ) {
7633  report( _( "You can't travel there." ) );
7634  return std::nullopt;
7635  }
7636  return shortest_route;
7637 }
bool is_dangerous_tile(const tripoint &dest_loc) const
Definition: game.cpp:10408
float rl_dist_exact(const tripoint &loc1, const tripoint &loc2)
Definition: line.cpp:259
tripoint_range< Tripoint > points_in_radius(const Tripoint &center, const int radius, const int radiusz=0)
Definition: map_iterator.h:154

References _, a, b, get_map, Character::get_pathfinding_settings(), is_dangerous_tile(), points_in_radius(), map::points_in_radius(), Creature::pos_bub(), coords::coord_point_mut< Point, Subpoint, InBounds >::raw(), rl_dist(), rl_dist_exact(), map::route(), and Character::sees().

Referenced by list_items(), look_around(), and try_get_left_click_action().

◆ save()

bool game::save ( )

Returns false if saving failed.

Definition at line 3472 of file game.cpp.

3473 {
3474  std::chrono::seconds time_since_load =
3475  std::chrono::duration_cast<std::chrono::seconds>(
3476  std::chrono::steady_clock::now() - time_of_last_load );
3477  std::chrono::seconds total_time_played = time_played_at_last_load + time_since_load;
3478  events().send<event_type::game_save>( time_since_load, total_time_played );
3479  try {
3480  if( !save_player_data() ||
3481  !save_achievements() ||
3483  !save_maps() ||
3485  !get_auto_notes_settings().save( true ) ||
3488  !write_to_file( PATH_INFO::world_base_save_path() + "/uistate.json", [&]( std::ostream & fout ) {
3489  JsonOut jsout( fout );
3490  uistate.serialize( jsout );
3491  }, _( "uistate data" ) ) ) {
3492  debugmsg( "game not saved" );
3493  return false;
3494  } else {
3495  world_generator->last_world_name = world_generator->active_world->world_name;
3496  world_generator->last_character_name = u.name;
3497  world_generator->save_last_world_info();
3498  world_generator->active_world->add_save( save_t::from_save_id( u.get_save_id() ) );
3500  u.get_save_id() ) + ".pt" ), [&total_time_played]( std::ostream & fout ) {
3501  fout.imbue( std::locale::classic() );
3502  fout << total_time_played.count();
3503  } );
3504 #if defined(EMSCRIPTEN)
3505  // This will allow the window to be closed without a prompt, until do_turn()
3506  // is called.
3507  EM_ASM( window.game_unsaved = false; );
3508 #endif
3509  return true;
3510  }
3511  } catch( std::ios::failure & ) {
3512  popup( _( "Failed to save game data" ) );
3513  return false;
3514  }
3515 }
void write_to_file(const std::string &path, const std::function< void(std::ostream &)> &writer)
Definition: json.h:736
bool save(bool bCharacter)
Definition: auto_note.cpp:43
bool save_maps()
Definition: game.cpp:3335
bool save_factions_missions_npcs()
Definition: game.cpp:3327
bool save_player_data()
Definition: game.cpp:3348
bool save_achievements()
Definition: game.cpp:3375
bool save_character()
void serialize(JsonOut &json) const
bool save_zones(std::string const &suffix={})
Definition: clzones.cpp:1698

References _, base64_encode(), debugmsg, events(), save_t::from_save_id(), game_save, get_auto_notes_settings(), get_auto_pickup(), zone_manager::get_manager(), get_safemode(), avatar::get_save_id(), Character::name, popup(), auto_notes::auto_note_settings::save(), save_achievements(), auto_pickup::player_settings::save_character(), safemode::save_character(), save_factions_missions_npcs(), save_maps(), save_player_data(), zone_manager::save_zones(), event_bus::send(), uistatedata::serialize(), time_of_last_load, time_played_at_last_load, u, uistate, PATH_INFO::world_base_save_path(), PATH_INFO::world_base_save_path_path(), world_generator, and write_to_file().

Referenced by do_regular_action(), quicksave(), and zones_manager().

◆ save_achievements()

bool game::save_achievements ( )
private

Definition at line 3375 of file game.cpp.

3376 {
3377  const std::string &achievement_dir = PATH_INFO::achievementdir();
3378 
3379  //Check if achievement dir exists
3380  if( !assure_dir_exist( achievement_dir ) ) {
3381  dbg( D_ERROR ) << "game:save_achievements: Unable to make achievement directory.";
3382  debugmsg( "Could not make '%s' directory", achievement_dir );
3383  return false;
3384  }
3385 
3386  // This sets the maximum length for the filename
3387  constexpr size_t suffix_len = 24 + 1;
3388  constexpr size_t max_name_len = FILENAME_MAX - suffix_len;
3389 
3390  const size_t name_len = u.name.size();
3391  // Here -1 leaves space for the ~
3392  const size_t truncated_name_len = ( name_len >= max_name_len ) ? ( max_name_len - 1 ) : name_len;
3393 
3394  std::ostringstream achievement_file_path;
3395 
3396  achievement_file_path << achievement_dir;
3397 
3398  if( get_options().has_option( "ENCODING_CONV" ) && !get_option<bool>( "ENCODING_CONV" ) ) {
3399  // Use the default locale to replace non-printable characters with _ in the player name.
3400  std::locale locale{ "C" };
3401  std::replace_copy_if( std::begin( u.name ), std::begin( u.name ) + truncated_name_len,
3402  std::ostream_iterator<char>( achievement_file_path ),
3403  [&]( const char c ) {
3404  return !std::isgraph( c, locale );
3405  }, '_' );
3406  } else {
3407  achievement_file_path << u.name;
3408  }
3409 
3410  // Add a ~ if the player name was actually truncated.
3411  achievement_file_path << ( ( truncated_name_len != name_len ) ? "~-" : "-" );
3413  const std::string json_path_string = achievement_file_path.str() + std::to_string(
3414  character_id ) + ".json";
3415 
3416  return write_to_file( json_path_string, [&]( std::ostream & fout ) {
3418  }, _( "player achievements" ) );
3419 
3420 }
std::string to_string(const time_duration &d, const bool compact)
Returns a string showing a duration.
Definition: calendar.cpp:546
void write_json_achievements(std::ostream &achievement_file, const std::string &avatar_name) const
int get_value() const
Definition: character_id.h:21
friend achievements_tracker & get_achievements()
Definition: game.cpp:13802
bool has_option(const std::string &name) const
Check if an option exists?
Definition: options.cpp:4134
std::string achievementdir()
Definition: path_info.cpp:334

References _, PATH_INFO::achievementdir(), assure_dir_exist(), c, D_ERROR, dbg, debugmsg, get_achievements, get_options(), get_player_character, character_id::get_value(), Character::getID(), options_manager::has_option(), Character::name, to_string(), u, achievements_tracker::write_json_achievements(), and write_to_file().

Referenced by save().

◆ save_cyborg()

void game::save_cyborg ( item cyborg,
const tripoint couch_pos,
Character installer 
)

Turns Broken Cyborg monster into Cyborg NPC via surgery.

Definition at line 5580 of file game.cpp.

5581 {
5582  int damage = cyborg->damage();
5583  int dmg_lvl = cyborg->damage_level();
5584  int difficulty = 12;
5585 
5586  if( damage != 0 ) {
5587 
5588  popup( _( "WARNING: Patient's body is damaged. Difficulty of the procedure is increased by %s." ),
5589  dmg_lvl );
5590 
5591  // Damage of the cyborg increases difficulty
5592  difficulty += dmg_lvl;
5593  }
5594 
5595  int chance_of_success = bionic_success_chance( true, -1, difficulty, installer );
5596  int success = chance_of_success - rng( 1, 100 );
5597 
5598  if( !get_avatar().query_yn(
5599  _( "WARNING: %i percent chance of SEVERE damage to all body parts! Continue anyway?" ),
5600  100 - static_cast<int>( chance_of_success ) ) ) {
5601  return;
5602  }
5603 
5604  if( success > 0 ) {
5605  add_msg( m_good, _( "Successfully removed Personality override." ) );
5606  add_msg( m_bad, _( "Autodoc immediately destroys the CBM upon removal." ) );
5607 
5608  m.i_rem( couch_pos, cyborg );
5609 
5610  shared_ptr_fast<npc> tmp = make_shared_fast<npc>();
5611  tmp->normalize();
5612  tmp->load_npc_template( npc_template_cyborg_rescued );
5613  tmp->spawn_at_precise( tripoint_abs_ms( get_map().getabs( couch_pos ) ) );
5614  overmap_buffer.insert_npc( tmp );
5615  tmp->hurtall( dmg_lvl * 10, nullptr );
5616  tmp->add_effect( effect_downed, rng( 1_turns, 4_turns ), false, 0, true );
5617  load_npcs();
5618 
5619  } else {
5620  const int failure_level = static_cast<int>( std::sqrt( std::abs( success ) * 4.0 * difficulty /
5621  installer.bionics_adjusted_skill( true, 12 ) ) );
5622  const int fail_type = std::min( 5, failure_level );
5623  switch( fail_type ) {
5624  case 1:
5625  case 2:
5626  add_msg( m_info, _( "The removal fails." ) );
5627  add_msg( m_bad, _( "The body is damaged." ) );
5628  cyborg->mod_damage( 1000 );
5629  break;
5630  case 3:
5631  case 4:
5632  add_msg( m_info, _( "The removal fails badly." ) );
5633  add_msg( m_bad, _( "The body is badly damaged!" ) );
5634  cyborg->mod_damage( 2000 );
5635  break;
5636  case 5:
5637  add_msg( m_info, _( "The removal is a catastrophe." ) );
5638  add_msg( m_bad, _( "The body is destroyed!" ) );
5639  m.i_rem( couch_pos, cyborg );
5640  break;
5641  default:
5642  break;
5643  }
5644 
5645  }
5646 
5647 }
int bionic_success_chance(bool autodoc, int skill_level, int difficulty, const Character &target)
Definition: bionics.cpp:2034
float bionics_adjusted_skill(bool autodoc, int skill_level=-1) const
Calculate skill for (un)installing bionics.
Definition: bionics.cpp:1983
bool mod_damage(int qty)
Apply damage to const itemrained by min_damage and max_damage.
Definition: item.cpp:8927
int damage_level(bool precise=false) const
Definition: item.cpp:876
int damage() const
How much damage has the item sustained?
Definition: item.cpp:858
map_stack::iterator i_rem(const tripoint &p, const map_stack::const_iterator &it)
Definition: map.cpp:5001
coords::coord_point< tripoint, coords::origin::abs, coords::ms > tripoint_abs_ms
Definition: coordinates.h:712
static const string_id< npc_template > npc_template_cyborg_rescued("cyborg_rescued")
double sqrt(std::vector< double > const &params)

References _, abs(), add_msg(), bionic_success_chance(), Character::bionics_adjusted_skill(), item::damage(), item::damage_level(), effect_downed, get_avatar, get_map, map::i_rem(), overmapbuffer::insert_npc(), load_npcs(), m, m_bad, m_good, m_info, min(), item::mod_damage(), npc_template_cyborg_rescued, overmap_buffer, popup(), query_yn(), rng(), and sqrt().

◆ save_factions_missions_npcs()

bool game::save_factions_missions_npcs ( )
private

Definition at line 3327 of file game.cpp.

3328 {
3329  std::string masterfile = PATH_INFO::world_base_save_path() + "/" + SAVE_MASTER;
3330  return write_to_file( masterfile, [&]( std::ostream & fout ) {
3331  serialize_master( fout );
3332  }, _( "factions data" ) );
3333 }
void serialize_master(std::ostream &fout)
Definition: savegame.cpp:1555

References _, SAVE_MASTER(), serialize_master(), PATH_INFO::world_base_save_path(), and write_to_file().

Referenced by save().

◆ save_maps()

bool game::save_maps ( )
private

Definition at line 3335 of file game.cpp.

3336 {
3337  try {
3338  m.save();
3339  overmap_buffer.save(); // can throw
3340  MAPBUFFER.save(); // can throw
3341  return true;
3342  } catch( const std::exception &err ) {
3343  popup( _( "Failed to save the maps: %s" ), err.what() );
3344  return false;
3345  }
3346 }
void save()
Add currently loaded submaps (in grid) to the mapbuffer.
Definition: map.cpp:7879
void save(bool delete_after_save=false)
Store all submaps in this instance into savefiles.
Definition: mapbuffer.cpp:122

References _, m, MAPBUFFER, overmap_buffer, popup(), map::save(), overmapbuffer::save(), and mapbuffer::save().

Referenced by save().

◆ save_player_data()

bool game::save_player_data ( )
private

Definition at line 3348 of file game.cpp.

3349 {
3350  const std::string playerfile = PATH_INFO::player_base_save_path();
3351 
3352  const bool saved_data = write_to_file( playerfile + SAVE_EXTENSION, [&]( std::ostream & fout ) {
3353  serialize( fout );
3354  }, _( "player data" ) );
3355  const bool saved_map_memory = u.save_map_memory();
3356  const bool saved_log = write_to_file( playerfile + SAVE_EXTENSION_LOG, [&](
3357  std::ostream & fout ) {
3358  memorial().save( fout );
3359  }, _( "player memorial" ) );
3360 #if defined(__ANDROID__)
3361  const bool saved_shortcuts = write_to_file( playerfile + SAVE_EXTENSION_SHORTCUTS, [&](
3362  std::ostream & fout ) {
3363  save_shortcuts( fout );
3364  }, _( "quick shortcuts" ) );
3365 #endif
3366  const bool saved_diary = u.get_avatar_diary()->store();
3367  return saved_data && saved_map_memory && saved_log && saved_diary
3368 #if defined(__ANDROID__)
3369  && saved_shortcuts
3370 #endif
3371  ;
3372 }
bool save_map_memory()
Definition: avatar.cpp:266
bool store()
Definition: diary.cpp:696
void serialize(std::ostream &fout)
Saving and loading functions.
Definition: savegame.cpp:83
memorial_logger & memorial()
Definition: game.cpp:3437
void save(std::ostream &) const
std::string player_base_save_path()
Definition: game.cpp:13248

References _, avatar::get_avatar_diary(), memorial(), PATH_INFO::player_base_save_path(), memorial_logger::save(), SAVE_EXTENSION(), SAVE_EXTENSION_LOG(), SAVE_EXTENSION_SHORTCUTS(), avatar::save_map_memory(), serialize(), diary::store(), u, and write_to_file().

Referenced by save().

◆ serialize()

void game::serialize ( std::ostream &  fout)

Saving and loading functions.

Definition at line 83 of file savegame.cpp.

84 {
85  /*
86  * Format version 12: Fully json, save the header. Weather and memorial exist elsewhere.
87  * To prevent (or encourage) confusion, there is no version 8. (cata 0.8 uses v7)
88  */
89  // Header
90  fout << "# version " << savegame_version << std::endl;
91 
92  JsonOut json( fout, true ); // pretty-print
93 
94  json.start_object();
95  // basic game state information.
96  json.member( "turn", calendar::turn );
97  json.member( "calendar_start", calendar::start_of_cataclysm );
98  json.member( "game_start", calendar::start_of_game );
99  json.member( "initial_season", static_cast<int>( calendar::initial_season ) );
100  json.member( "auto_travel_mode", auto_travel_mode );
101  json.member( "run_mode", static_cast<int>( safe_mode ) );
102  json.member( "mostseen", mostseen );
103  // current map coordinates
104  tripoint_abs_sm pos_abs_sm = m.get_abs_sub();
105  point_abs_om pos_om;
106  tripoint_om_sm pos_sm;
107  std::tie( pos_om, pos_sm ) = project_remain<coords::om>( pos_abs_sm );
108  json.member( "levx", pos_sm.x() );
109  json.member( "levy", pos_sm.y() );
110  json.member( "levz", pos_sm.z() );
111  json.member( "om_x", pos_om.x() );
112  json.member( "om_y", pos_om.y() );
113  // view offset
114  json.member( "view_offset_x", u.view_offset.x );
115  json.member( "view_offset_y", u.view_offset.y );
116  json.member( "view_offset_z", u.view_offset.z );
117 
118  json.member( "grscent", scent.serialize() );
119  json.member( "typescent", scent.serialize( true ) );
120 
121  // Then each monster
122  json.member( "active_monsters", *critter_tracker );
123 
124  json.member( "driving_view_offset", driving_view_offset );
125  json.member( "turnssincelastmon", turnssincelastmon );
126  json.member( "bVMonsterLookFire", bVMonsterLookFire );
127 
128  // save stats.
129  json.member( "kill_tracker", *kill_tracker_ptr );
130  json.member( "stats_tracker", *stats_tracker_ptr );
131  json.member( "achievements_tracker", *achievements_tracker_ptr );
132 
133  json.member( "player", u );
134  json.member( "inactive_global_effect_on_condition_vector",
136 
137  //save queued effect_on_conditions
139  json.member( "queued_global_effect_on_conditions" );
140  json.start_array();
141  while( !temp_queued.empty() ) {
142  json.start_object();
143  json.member( "time", temp_queued.top().time );
144  json.member( "eoc", temp_queued.top().eoc );
145  json.member( "context", temp_queued.top().context );
146  json.end_object();
147  temp_queued.pop();
148  }
149  json.end_array();
151  Messages::serialize( json );
152  json.member( "unique_npcs", unique_npcs );
153  json.end_object();
154 }
queued_eocs queued_global_effect_on_conditions
Definition: game.h:1095
global_variables global_variables_instance
Definition: game.h:1087
std::vector< effect_on_condition_id > inactive_global_effect_on_condition_vector
Definition: game.h:1094
void serialize(JsonOut &jsout) const
Definition: savegame.cpp:1595
std::string serialize(bool is_type=false) const
Definition: savegame.cpp:156
void serialize(JsonOut &json)
Definition: messages.cpp:434
time_point start_of_cataclysm
Definition: calendar.cpp:36
season_type initial_season
Definition: calendar.cpp:39
const int savegame_version
Definition: savegame.cpp:71

References achievements_tracker_ptr, auto_travel_mode, bVMonsterLookFire, queued_eoc::context, critter_tracker, driving_view_offset, queued_eocs::empty(), JsonOut::end_array(), JsonOut::end_object(), queued_eoc::eoc, map::get_abs_sub(), global_variables_instance, inactive_global_effect_on_condition_vector, calendar::initial_season, kill_tracker_ptr, m, JsonOut::member(), mostseen, queued_eocs::pop(), queued_global_effect_on_conditions, safe_mode, savegame_version, scent, scent_map::serialize(), Messages::serialize(), global_variables::serialize(), JsonOut::start_array(), JsonOut::start_object(), calendar::start_of_cataclysm, calendar::start_of_game, stats_tracker_ptr, queued_eoc::time, queued_eocs::top(), calendar::turn, turnssincelastmon, u, unique_npcs, Character::view_offset, coords::coord_point_mut< Point, Subpoint, InBounds >::x(), tripoint::x, coords::coord_point_mut< Point, Subpoint, InBounds >::y(), tripoint::y, coords::coord_point_mut< Point, Subpoint, InBounds >::z(), and tripoint::z.

Referenced by save_player_data().

◆ serialize_master()

void game::serialize_master ( std::ostream &  fout)
private

Definition at line 1555 of file savegame.cpp.

1556 {
1557  fout << "# version " << savegame_version << std::endl;
1558  try {
1559  JsonOut json( fout, true ); // pretty-print
1560  json.start_object();
1561 
1562  json.member( "next_mission_id", next_mission_id );
1563  json.member( "next_npc_id", next_npc_id );
1564 
1565  json.member( "active_missions" );
1566  mission::serialize_all( json );
1567  json.member( "overmapbuffer" );
1569 
1570  json.member( "timed_events" );
1572 
1573  json.member( "factions", *faction_manager_ptr );
1574  json.member( "seed", seed );
1575 
1576  json.member( "weather" );
1578 
1579  json.end_object();
1580  } catch( const JsonError &e ) {
1581  debugmsg( "error saving to %s: %s", SAVE_MASTER, e.c_str() );
1582  }
1583 }
const char * c_str() const noexcept
Definition: json_error.h:11
static void serialize_all(JsonOut &json)
Definition: savegame.cpp:1447
void serialize_overmap_global_state(JsonOut &json) const
Writes metadata about special placement as a JSON value.
Definition: savegame.cpp:1703
static void serialize_all(JsonOut &jsout)
Definition: savegame.cpp:1609
static void serialize_all(JsonOut &json)
Definition: savegame.cpp:1456

References JsonError::c_str(), debugmsg, JsonOut::end_object(), faction_manager_ptr, JsonOut::member(), next_mission_id, next_npc_id, overmap_buffer, SAVE_MASTER(), savegame_version, seed, mission::serialize_all(), weather_manager::serialize_all(), timed_event_manager::serialize_all(), overmapbuffer::serialize_overmap_global_state(), and JsonOut::start_object().

Referenced by save_factions_missions_npcs().

◆ set_critter_died()

void game::set_critter_died ( )

If invoked, dead will be cleaned this turn.

Definition at line 1602 of file game.cpp.

1603 {
1604  critter_died = true;
1605 }

References critter_died.

◆ set_driving_view_offset()

void game::set_driving_view_offset ( const point p)

Definition at line 1415 of file game.cpp.

1416 {
1417  // remove the previous driving offset,
1418  // store the new offset and apply the new offset.
1421  driving_view_offset.x = p.x;
1422  driving_view_offset.y = p.y;
1425 }

References driving_view_offset, u, Character::view_offset, point::x, tripoint::x, point::y, and tripoint::y.

Referenced by calc_driving_offset().

◆ set_npcs_dirty()

void game::set_npcs_dirty ( )

If invoked, NPCs will be reloaded before next turn.

Definition at line 1597 of file game.cpp.

1598 {
1599  npcs_dirty = true;
1600 }

References npcs_dirty.

◆ set_safe_mode()

void game::set_safe_mode ( safe_mode_type  mode)

Definition at line 10367 of file game.cpp.

10368 {
10369  safe_mode = mode;
10370  safe_mode_warning_logged = false;
10371 }

References safe_mode, and safe_mode_warning_logged.

Referenced by do_regular_action(), and mon_info_update().

◆ set_zoom()

void game::set_zoom ( int  level)

Definition at line 8203 of file game.cpp.

8204 {
8205 #if defined(TILES)
8206  if( tileset_zoom != level ) {
8207  tileset_zoom = level;
8208  rescale_tileset( tileset_zoom );
8209  }
8210 #else
8211  static_cast<void>( level );
8212 #endif // TILES
8213 }

References tileset_zoom.

Referenced by look_around().

◆ setremoteveh()

void game::setremoteveh ( vehicle veh)

Sets the current remotely controlled vehicle.

Definition at line 2634 of file game.cpp.

2635 {
2637  remoteveh_cache = veh;
2638  if( veh != nullptr && !u.has_active_bionic( bio_remote ) &&
2640  debugmsg( "Tried to set remote vehicle without bio_remote or remotevehcontrol" );
2641  veh = nullptr;
2642  }
2643 
2644  if( veh == nullptr ) {
2645  u.remove_value( "remote_controlling_vehicle" );
2646  return;
2647  }
2648 
2649  std::stringstream remote_veh_string;
2650  const tripoint vehpos = veh->global_pos3();
2651  remote_veh_string << vehpos.x << ' ' << vehpos.y << ' ' << vehpos.z;
2652  u.set_value( "remote_controlling_vehicle", remote_veh_string.str() );
2653 }
void remove_value(const std::string &key)
Definition: creature.cpp:1954

References bio_remote, debugmsg, vehicle::global_pos3(), Character::has_active_bionic(), Character::has_active_item(), itype_remotevehcontrol, remoteveh_cache, remoteveh_cache_time, Creature::remove_value(), Creature::set_value(), calendar::turn, u, tripoint::x, tripoint::y, and tripoint::z.

◆ setup()

void game::setup ( )

Definition at line 764 of file game.cpp.

765 {
766  loading_ui ui( true );
767  new_game = true;
768  {
771  popup.message( "%s", _( "Please wait while the world data loads…\nLoading core data" ) );
773  refresh_display();
774 
775  load_core_data( ui );
776  }
778  // Panel manager needs JSON data to be loaded before init
780 
781  m = map();
782 
783  next_npc_id = character_id( 1 );
784  next_mission_id = 1;
785  uquit = QUIT_NO; // We haven't quit the game
786  bVMonsterLookFire = true;
787 
788  // invalidate calendar caches in case we were previously playing
789  // a different world
790  calendar::set_eternal_season( ::get_option<bool>( "ETERNAL_SEASON" ) );
791  calendar::set_season_length( ::get_option<int>( "SEASON_LENGTH" ) );
792 
793  calendar::set_eternal_night( ::get_option<std::string>( "ETERNAL_TIME_OF_DAY" ) == "night" );
794  calendar::set_eternal_day( ::get_option<std::string>( "ETERNAL_TIME_OF_DAY" ) == "day" );
795 
796  calendar::set_location( ::get_option<float>( "LATITUDE" ), ::get_option<float>( "LONGITUDE" ) );
797 
799  // Weather shift in 30
801 
802  turnssincelastmon = 0_turns; //Auto safe mode init
803 
805  clear_zombies();
806  critter_tracker->clear_npcs();
807  faction_manager_ptr->clear();
811 
812  SCT.vSCT.clear(); //Delete pending messages
813 
814  stats().clear();
815  // reset kill counts
816  kill_tracker_ptr->clear();
817  achievements_tracker_ptr->clear();
818  eoc_events_ptr->clear();
819  // reset follower list
820  follower_ids.clear();
821  scent.reset();
823  u.character_mood_face( true );
825  remoteveh_cache = nullptr;
826  global_variables &globvars = get_globals();
827  globvars.clear_global_values();
828  unique_npcs.clear();
830  // back to menu for save loading, new game etc
831 }
const mood_face_id & character_mood_face(bool clear_cache=false) const
Definition: mood_face.cpp:66
Helper class that fills the background and obscures all UIs below.
Definition: ui_manager.h:261
void clear_zombies()
Redirects to the creature_tracker clear() function.
Definition: game.cpp:5290
bool new_game
True if the game has just started or loaded, else false.
Definition: game.h:1105
void load_world_modfiles(loading_ui &ui)
Loads core data and mods from the active world.
Definition: game.cpp:3236
friend global_variables & get_globals()
Definition: game.cpp:13871
void clear_global_values()
Definition: global_vars.h:44
static void clear_all()
Remove all active missions, used to cleanup on exit and before reloading a new game.
Definition: mission.cpp:155
void init()
Definition: panels.cpp:406
void reset()
Definition: scent_map.cpp:52
weather_type_id weather_override
Definition: weather.h:219
void clear_messages()
Definition: messages.cpp:464
void set_location(float latitude, float longitude)
Definition: calendar.cpp:735
void clear(Character &you)
clear all queued and inactive eocs
void reset_sounds()
Definition: sounds.cpp:785
const weather_type_id WEATHER_NULL("null")
const weather_type_id WEATHER_CLEAR("clear")

References _, achievements_tracker_ptr, calendar::before_time_starts, bVMonsterLookFire, character_id, avatar::character_mood_face(), stats_tracker::clear(), effect_on_conditions::clear(), mission::clear_all(), global_variables::clear_global_values(), Messages::clear_messages(), clear_zombies(), critter_tracker, eoc_events_ptr, faction_manager_ptr, follower_ids, get_globals, panel_manager::get_manager(), get_weather, panel_manager::init(), kill_tracker_ptr, load_core_data(), load_world_modfiles(), m, map, new_game, next_mission_id, next_npc_id, weather_manager::nextweather, popup(), QUIT_NO, ui_manager::redraw(), refresh_display(), remoteveh_cache, remoteveh_cache_time, scent_map::reset(), sounds::reset_sounds(), scent, SCT, calendar::set_eternal_day(), calendar::set_eternal_night(), calendar::set_eternal_season(), calendar::set_location(), calendar::set_season_length(), calendar::start_of_game, stats(), timed_events, turnssincelastmon, u, unique_npcs, uquit, scrollingcombattext::vSCT, weather, WEATHER_CLEAR(), weather_manager::weather_id, WEATHER_NULL(), and weather_manager::weather_override.

◆ shared_from()

template<typename T >
template shared_ptr_fast< npc > game::shared_from< npc > ( const T &  critter)

Returns a shared pointer to the given critter (which can be of any of the subclasses of Creature).

The function may return an empty pointer if the given critter is not stored anywhere (e.g. it was allocated on the stack, not stored in the critter_tracker nor in active_npc nor is it u).

Definition at line 5125 of file game.cpp.

5126 {
5127  if( static_cast<const Creature *>( &critter ) == static_cast<const Creature *>( &u ) ) {
5128  // u is not stored in a shared_ptr, but it won't go out of scope anyway
5129  return std::dynamic_pointer_cast<T>( u_shared_ptr );
5130  }
5131  if( critter.is_monster() ) {
5132  if( const shared_ptr_fast<monster> mon_ptr = critter_tracker->find( critter.get_location() ) ) {
5133  if( static_cast<const Creature *>( mon_ptr.get() ) == static_cast<const Creature *>( &critter ) ) {
5134  return std::dynamic_pointer_cast<T>( mon_ptr );
5135  }
5136  }
5137  }
5138  if( critter.is_npc() ) {
5139  for( auto &cur_npc : critter_tracker->active_npc ) {
5140  if( static_cast<const Creature *>( cur_npc.get() ) == static_cast<const Creature *>( &critter ) ) {
5141  return std::dynamic_pointer_cast<T>( cur_npc );
5142  }
5143  }
5144  }
5145  return nullptr;
5146 }

References critter_tracker, u, and u_shared_ptr.

Referenced by list_monsters(), mon_info_update(), and validate_mounted_npcs().

◆ shift_destination_preview()

void game::shift_destination_preview ( const point delta)

Definition at line 13274 of file game.cpp.

13275 {
13276  for( tripoint_bub_ms &p : destination_preview ) {
13277  p += delta;
13278  }
13279 }

References destination_preview.

◆ shift_monsters()

void game::shift_monsters ( const tripoint shift)
private

Shift all active monsters, the shift vector is the number of shifted submaps.

Monsters that are outside of the reality bubble after shifting are despawned. Note on z-levels: this works with vertical shifts, but currently all monsters are despawned upon a vertical shift.

Definition at line 12776 of file game.cpp.

12777 {
12778  if( shift == tripoint_zero ) {
12779  return;
12780  }
12781  for( monster &critter : all_monsters() ) {
12782  if( shift.xy() != point_zero ) {
12783  critter.shift( shift.xy() );
12784  }
12785 
12786  if( m.inbounds( critter.pos() ) ) {
12787  // We're inbounds, so don't despawn after all.
12788  continue;
12789  }
12790  // The critter is now outside of the reality bubble; it must be saved and removed.
12791  despawn_monster( critter );
12792  }
12793 }

References all_monsters(), despawn_monster(), map::inbounds(), m, point_zero, shift, and tripoint_zero.

Referenced by update_map().

◆ slip_down()

bool game::slip_down ( climb_maneuver  maneuver,
climbing_aid_id  aid = climbing_aid_id::NULL_ID(),
bool  show_chance_messages = true 
)

Checks if player is able to successfully climb to/from some terrain and not slip down.

Parameters
maneuverType & direction of climbing maneuver. Affects chance and whether traps trigger.
aidIdentifies the object, terrain or ability being used to climb. See climbing.h.
show_chance_messagesIf true, adds explanatory messages to the log when calculating fall chance.
Returns
whether player has slipped down

Definition at line 13417 of file game.cpp.

13419 {
13420  int slip = slip_down_chance( maneuver, aid_id, show_chance_messages );
13421 
13422  if( x_in_y( slip, 100 ) ) {
13423  add_msg( m_bad, _( "You slip while climbing and fall down." ) );
13424  if( slip >= 100 ) {
13425  add_msg( m_bad, _( "Climbing is impossible in your current state." ) );
13426  }
13427  // Check for traps if climbing UP or DOWN. Note that ledges (open air) count as traps.
13428  if( maneuver != climb_maneuver::over_obstacle ) {
13429  m.creature_on_trap( u );
13430  }
13431  return true;
13432  }
13433  return false;
13434 }

References _, add_msg(), map::creature_on_trap(), m, m_bad, over_obstacle, slip_down_chance(), u, and x_in_y().

Referenced by vertical_move().

◆ slip_down_chance()

int game::slip_down_chance ( climb_maneuver  maneuver,
climbing_aid_id  aid = climbing_aid_id::NULL_ID(),
bool  show_chance_messages = true 
)

Calculates the chance that slip_down will return true.

Parameters
maneuverType & direction of climbing maneuver. Affects chance and whether traps trigger.
affordanceIdentifies the object, terrain or ability being used to climb. See climbing.h.
show_messagesIf true, outputs climbing chance factors to the message log as if attempting.
Returns
Probability, as a percentage, that player will slip down while climbing some terrain.
Dexterity decreases chances of slipping while climbing \EFFECT_STR decreases chances of slipping while climbing Not using arm strength since lifting score comes into play later

Definition at line 13281 of file game.cpp.

13283 {
13284  if( aid_id.is_null() ) {
13285  // The NULL climbing aid ID may be passed as a default argument.
13286  aid_id = climbing_aid_default;
13287  }
13288 
13289  const climbing_aid &aid = aid_id.obj();
13290 
13291  int slip = 100;
13292 
13293  const bool parkour = u.has_proficiency( proficiency_prof_parkour );
13294  const bool badknees = u.has_trait( trait_BADKNEES );
13295  if( parkour && badknees ) {
13296  if( show_chance_messages ) {
13297  add_msg( m_info, _( "Your skill in parkour makes up for your bad knees while climbing." ) );
13298  }
13299  } else if( u.has_proficiency( proficiency_prof_parkour ) ) {
13300  slip /= 2;
13301  if( show_chance_messages ) {
13302  add_msg( m_info, _( "Your skill in parkour makes it easier to climb." ) );
13303  }
13304  } else if( u.has_trait( trait_BADKNEES ) ) {
13305  slip *= 2;
13306  if( show_chance_messages ) {
13307  add_msg( m_info, _( "Your bad knees make it difficult to climb." ) );
13308  }
13309  }
13310 
13311  add_msg_debug( debugmode::DF_GAME, "Slip chance after proficiency/trait modifiers %d%%", slip );
13312 
13313  // Climbing is difficult with wet hands and feet.
13314  float wet_penalty = 1.0f;
13315  bool wet_feet = false;
13316  bool wet_hands = false;
13317 
13320  if( u.get_part_wetness( bp ) > 0 ) {
13321  add_msg_debug( debugmode::DF_GAME, "Foot %s %.1f wet", body_part_name( bp ),
13323  wet_feet = true;
13324  wet_penalty += u.get_part( bp )->get_wetness_percentage() / 2;
13325  }
13326  }
13327 
13330  if( u.get_part_wetness( bp ) > 0 ) {
13331  add_msg_debug( debugmode::DF_GAME, "Hand %s %.1f wet", body_part_name( bp ),
13333  wet_hands = true;
13334  wet_penalty += u.get_part( bp )->get_wetness_percentage() / 2;
13335  }
13336  }
13337  if( show_chance_messages ) {
13338  if( wet_feet && wet_hands ) {
13339  add_msg( m_info, _( "Your wet hands and feet make it harder to climb." ) );
13340  } else if( wet_feet ) {
13341  add_msg( m_info, _( "Your wet feet make it harder to climb." ) );
13342  } else if( wet_hands ) {
13343  add_msg( m_info, _( "Your wet hands make it harder to climb." ) );
13344  }
13345  }
13346 
13347  // Apply wetness penalty
13348  slip *= wet_penalty;
13349 
13350  add_msg_debug( debugmode::DF_GAME, "Slip chance after wetness penalty %d%%", slip );
13351 
13352  ///\EFFECT_DEX decreases chances of slipping while climbing
13353  ///\EFFECT_STR decreases chances of slipping while climbing
13354  /// Not using arm strength since lifting score comes into play later
13355  slip /= std::max( 1, u.dex_cur + u.str_cur );
13356 
13357  add_msg_debug( debugmode::DF_GAME, "Slip chance after stat modifiers %d%%", slip );
13358 
13359  // Apply limb score penalties - grip, arm strength and footing are all relevant
13361  add_msg_debug( debugmode::DF_GAME, "Slipping chance after limb scores %d%%", slip );
13362 
13363  // Being weighed down makes it easier for you to slip.
13364  double weight_ratio = static_cast<double>( units::to_gram( u.weight_carried() ) ) / units::to_gram(
13365  u.weight_capacity() );
13366  slip += roll_remainder( 8.0 * weight_ratio );
13367  add_msg_debug( debugmode::DF_GAME, "Weight ratio %.2f, slip chance %d%%", weight_ratio,
13368  slip );
13369 
13370  // Decreasing stamina makes you slip up more often
13371  const float stamina_ratio = static_cast<float>( u.get_stamina() ) / u.get_stamina_max();
13372  if( stamina_ratio < 0.8 ) {
13373  slip /= std::max( stamina_ratio, .1f );
13374 
13375  if( show_chance_messages ) {
13376  if( stamina_ratio > 0.6 ) {
13377  add_msg( m_info, _( "You are winded, which makes climbing harder." ) );
13378  } else if( stamina_ratio > 0.4 ) {
13379  add_msg( m_info, _( "You are out of breath, which makes climbing much harder." ) );
13380  } else if( stamina_ratio > 0.2 ) {
13381  add_msg( m_info, _( "You can't catch your breath, which makes it much more difficult to climb." ) );
13382  } else {
13383  add_msg( m_info, _( "You feel faint and can't keep your balance." ) );
13384  }
13385  }
13386  }
13387  add_msg_debug( debugmode::DF_GAME, "Stamina ratio %.2f, slip chance %d%%",
13388  stamina_ratio, slip );
13389 
13390  if( show_chance_messages ) {
13391  if( weight_ratio >= 1 ) {
13392  add_msg( m_info, _( "Your carried weight tries to drag you down." ) );
13393  } else if( weight_ratio > .75 ) {
13394  add_msg( m_info, _( "You strain to climb with the weight of your possessions." ) );
13395  } else if( weight_ratio > .5 ) {
13396  add_msg( m_info, _( "You feel the weight of your luggage makes it more difficult to climb." ) );
13397  } else if( weight_ratio > .25 ) {
13398  add_msg( m_info, _( "Your carried weight makes it a little harder to climb." ) );
13399  }
13400  }
13401 
13402  // Affordances (other than ledge) may reduce slip chance, even below zero.
13403  slip += aid.slip_chance_mod;
13404  if( show_chance_messages ) {
13405  if( aid.slip_chance_mod >= 0 ) {
13406  // TODO allow for a message specific to the climbing aid?
13407  add_msg( m_info, _( "There's nothing here to help you climb." ) );
13408  }
13409  }
13410 
13411  add_msg_debug( debugmode::DF_GAME, "After affordance modifier, final slip chance %d%%",
13412  slip );
13413 
13414  return slip;
13415 }
std::string body_part_name(const bodypart_id &bp, int number)
Returns the matching name of the body_part token.
Definition: bodypart.cpp:791
units::mass weight_capacity() const override
Definition: character.cpp:3197
float get_modifier(const character_modifier_id &mod, const skill_id &skill=skill_id::NULL_ID()) const
int str_cur
Definition: character.h:577
units::mass weight_carried() const
Definition: character.cpp:3088
int get_stamina_max() const
Definition: character.cpp:6815
int get_part_wetness(const bodypart_id &id) const
Definition: creature.cpp:2312
std::vector< bodypart_id > get_all_body_parts_of_type(body_part_type::type part_type, get_body_part_flags flags=get_body_part_flags::none) const
Definition: creature.cpp:2659
bodypart * get_part(const bodypart_id &id)
Definition: creature.cpp:2185
float get_wetness_percentage() const
Definition: bodypart.cpp:894
int slip_chance_mod
Definition: climbing.h:152
static const trait_id trait_BADKNEES("BADKNEES")
static const character_modifier_id character_modifier_slip_prevent_mod("slip_prevent_mod")
constexpr value_type to_gram(const quantity< value_type, mass_in_milligram_tag > &v)
Definition: units.h:364
int roll_remainder(double value)
Definition: rng.cpp:134

References _, add_msg(), add_msg_debug, body_part_name(), bp, character_modifier_slip_prevent_mod, climbing_aid_default, Character::dex_cur, debugmode::DF_GAME, body_part_type::foot, Creature::get_all_body_parts_of_type(), Character::get_modifier(), Creature::get_part(), Creature::get_part_wetness(), Character::get_stamina(), Character::get_stamina_max(), bodypart::get_wetness_percentage(), body_part_type::hand, Character::has_proficiency(), Character::has_trait(), string_id< T >::is_null(), m_info, max(), string_id< T >::obj(), primary_type, proficiency_prof_parkour, roll_remainder(), climbing_aid::slip_chance_mod, Character::str_cur, units::to_gram(), trait_BADKNEES, u, Character::weight_capacity(), and Character::weight_carried().

Referenced by climb_down_using(), and slip_down().

◆ spawn_hallucination() [1/2]

bool game::spawn_hallucination ( const tripoint p)

Spawns a hallucination at a determined position.

Attempts to spawn a hallucination at given location.

Returns false if the hallucination couldn't be spawned for whatever reason, such as a monster already in the target square.

Returns
Whether or not a hallucination was successfully spawned.

Definition at line 5343 of file game.cpp.

5344 {
5345  //Don't spawn hallucinations on open air
5346  if( get_map().has_flag( ter_furn_flag::TFLAG_NO_FLOOR, p ) ) {
5347  return false;
5348  }
5349 
5350  if( one_in( 100 ) ) {
5351  shared_ptr_fast<npc> tmp = make_shared_fast<npc>();
5352  tmp->normalize();
5353  tmp->randomize( NC_HALLU );
5354  tmp->spawn_at_precise( tripoint_abs_ms( get_map().getabs( p ) ) );
5355  if( !get_creature_tracker().creature_at( p, true ) ) {
5356  overmap_buffer.insert_npc( tmp );
5357  load_npcs();
5358  return true;
5359  } else {
5360  return false;
5361  }
5362  }
5363 
5365 
5366  // If there's 'spawns' exist for player's current location, then
5367  // spawn random hallucination monster from 'spawns'-dependent monster group (90% chance)
5368  // or a completely random hallucination monster (10% chance)
5369  const oter_id &terrain_type = overmap_buffer.ter( get_player_character().global_omt_location() );
5370  const overmap_static_spawns &spawns = terrain_type->get_static_spawns();
5371  if( !spawns.group.is_null() && !one_in( 9 ) ) {
5373  }
5374 
5375  return spawn_hallucination( p, hallu, std::nullopt );
5376 }
mtype_id get_valid_hallucination() const
static MonsterGenerator & generator()
static const mtype_id & GetRandomMonsterFromGroup(const mongroup_id &group)
Gets a random monster, weighted by frequency.
Definition: mongroup.cpp:619
bool spawn_hallucination(const tripoint &p)
Spawns a hallucination at a determined position.
Definition: game.cpp:5343
bool is_null() const
Returns whether this represents the id of the null-object (in which case it's the null-id).
Definition: string_id.h:322
const npc_class_id NC_HALLU("NC_HALLU")
const overmap_static_spawns & get_static_spawns() const
Definition: omdata.h:382
string_id< MonsterGroup > group
Definition: omdata.h:143

References MonsterGenerator::generator(), get_creature_tracker, get_map, get_player_character, oter_t::get_static_spawns(), MonsterGenerator::get_valid_hallucination(), MonsterGroupManager::GetRandomMonsterFromGroup(), overmap_spawns::group, overmapbuffer::insert_npc(), string_id< T >::is_null(), load_npcs(), NC_HALLU, one_in(), overmap_buffer, overmapbuffer::ter(), and TFLAG_NO_FLOOR.

◆ spawn_hallucination() [2/2]

bool game::spawn_hallucination ( const tripoint p,
const mtype_id mt,
std::optional< time_duration lifespan 
)

Spawns a hallucination at a determined position of a given monster.

Attempts to spawn a hallucination at given location.

Returns false if the hallucination couldn't be spawned for whatever reason, such as a monster already in the target square.

Returns
Whether or not a hallucination was successfully spawned.

Definition at line 5383 of file game.cpp.

5385 {
5386  //Don't spawn hallucinations on open air
5387  if( get_map().has_flag( ter_furn_flag::TFLAG_NO_FLOOR, p ) ) {
5388  return false;
5389  }
5390 
5391  const shared_ptr_fast<monster> phantasm = make_shared_fast<monster>( mt );
5392  phantasm->hallucination = true;
5393  phantasm->spawn( p );
5394  if( lifespan.has_value() ) {
5395  phantasm->set_summon_time( lifespan.value() );
5396  }
5397  //Don't attempt to place phantasms inside of other creatures
5398  if( !get_creature_tracker().creature_at( phantasm->pos(), true ) ) {
5399  return critter_tracker->add( phantasm );
5400  } else {
5401  return false;
5402  }
5403 }

References critter_tracker, get_creature_tracker, get_map, and TFLAG_NO_FLOOR.

◆ spawn_npc()

bool game::spawn_npc ( const tripoint p,
const string_id< npc_template > &  npc_class,
std::string &  unique_id,
std::vector< trait_id > &  traits,
std::optional< time_duration lifespan 
)

Spawns a npc at a determined position.

Definition at line 5405 of file game.cpp.

5408 {
5409  if( !unique_id.empty() && g->unique_npc_exists( unique_id ) ) {
5410  add_msg_debug( debugmode::DF_NPC, "NPC with unique id %s already exists.", unique_id );
5411  return false;
5412  }
5413  shared_ptr_fast<npc> tmp = make_shared_fast<npc>();
5414  tmp->normalize();
5415  tmp->load_npc_template( npc_class );
5416  tmp->spawn_at_precise( tripoint_abs_ms( get_map().getabs( p ) ) );
5417  if( !get_creature_tracker().creature_at( p, true ) ) {
5418  overmap_buffer.insert_npc( tmp );
5419  for( const trait_id &new_trait : traits ) {
5420  tmp->set_mutation( new_trait );
5421  }
5422  if( !unique_id.empty() ) {
5423  tmp->set_unique_id( unique_id );
5424  }
5425  if( lifespan.has_value() ) {
5426  tmp->set_summon_time( lifespan.value() );
5427  }
5428  load_npcs();
5429  return true;
5430  } else {
5431  return false;
5432  }
5433 }

References add_msg_debug, debugmode::DF_NPC, g, get_creature_tracker, get_map, overmapbuffer::insert_npc(), load_npcs(), and overmap_buffer.

◆ spell_events_subscriber()

spell_events & game::spell_events_subscriber ( )

Definition at line 3467 of file game.cpp.

3468 {
3469  return *spell_events_ptr;
3470 }

References spell_events_ptr.

◆ start_calendar()

void game::start_calendar ( )

Definition at line 13102 of file game.cpp.

13103 {
13107  calendar::initial_season = static_cast<season_type>( ( to_days<int>( calendar::start_of_game -
13108  calendar::turn_zero ) / get_option<int>( "SEASON_LENGTH" ) ) % season_type::NUM_SEASONS );
13109 }
season_type
Real world seasons.
Definition: calendar.h:21
@ NUM_SEASONS
Definition: calendar.h:26
const scenario * scen
Definition: game.h:1081
time_point start_of_cataclysm() const
Definition: scenario.cpp:598
time_point start_of_game() const
Definition: scenario.cpp:603

References calendar::initial_season, NUM_SEASONS, scen, calendar::start_of_cataclysm, scenario::start_of_cataclysm(), calendar::start_of_game, scenario::start_of_game(), calendar::turn, and calendar::turn_zero.

Referenced by start_game().

◆ start_game()

bool game::start_game ( )
private

Definition at line 850 of file game.cpp.

851 {
852  if( !gamemode ) {
853  gamemode = std::make_unique<special_game>();
854  }
855 
856  seed = rng_bits();
857  new_game = true;
858  start_calendar();
860  safe_mode = ( get_option<bool>( "SAFEMODE" ) ? SAFE_MODE_ON : SAFE_MODE_OFF );
861  mostseen = 0; // ...and mostseen is 0, we haven't seen any monsters yet.
863 
864  init_autosave();
865 
868  popup.message( "%s", _( "Please wait as we build your world" ) );
870  refresh_display();
871 
872  load_master();
873  u.setID( assign_npc_id() ); // should be as soon as possible, but *after* load_master
874 
875  // Make sure the items are added after the calendar is started
877  // Move items from the inventory. eventually the inventory should not contain items at all.
878  u.migrate_items_to_storage( true );
879 
881  u.start_location.obj();
883  std::unordered_map<std::string, std::string> associated_parameters;
884  const bool select_starting_city = get_option<bool>( "SELECT_STARTING_CITY" );
885  do {
886  if( select_starting_city ) {
887  if( !u.starting_city.has_value() ) {
889  u.world_origin = u.starting_city->pos_om;
890  }
891  auto ret = start_loc.find_player_initial_location( u.starting_city.value() );
892  omtstart = ret.first;
893  associated_parameters = ret.second;
894  } else {
895  auto ret = start_loc.find_player_initial_location( u.world_origin.value_or( point_abs_om() ) );
896  omtstart = ret.first;
897  associated_parameters = ret.second;
898  }
899  if( omtstart == overmap::invalid_tripoint ) {
900 
901  MAPBUFFER.clear();
903 
904  if( !query_yn(
905  _( "Try again?\n\nIt may require several attempts until the game finds a valid starting location." ) ) ) {
906  return false;
907  }
908  }
909  } while( omtstart == overmap::invalid_tripoint );
910 
911  // Set parameter(s) if specified in chosen start_loc
912  start_loc.set_parameters( omtstart, associated_parameters );
913 
914  start_loc.prepare_map( omtstart );
915 
916  if( scen->has_map_extra() ) {
917  // Map extras can add monster spawn points and similar and should be done before the main
918  // map is loaded.
919  start_loc.add_map_extra( omtstart, scen->get_map_extra() );
920  }
921 
922  tripoint_abs_sm lev = project_to<coords::sm>( omtstart );
923  // The player is centered in the map, but lev[xyz] refers to the top left point of the map
924  lev -= point( HALF_MAPSIZE, HALF_MAPSIZE );
925  load_map( lev, /*pump_events=*/true );
926 
927  int level = m.get_abs_sub().z();
928  u.setpos( m.getlocal( project_to<coords::ms>( omtstart ) ) );
929  m.invalidate_map_cache( level );
930  m.build_map_cache( level );
931  // Do this after the map cache has been built!
932  start_loc.place_player( u, omtstart );
933  // ...but then rebuild it, because we want visibility cache to avoid spawning monsters in sight
934  m.invalidate_map_cache( level );
935  m.build_map_cache( level );
936  // Start the overmap with out immediate neighborhood visible, this needs to be after place_player
938  get_option<int>( "DISTANCE_INITIAL_VISIBILITY" ), 0 );
939 
940  const int city_size = get_option<int>( "CITY_SIZE" );
941  if( get_scenario()->get_reveal_locale() && city_size > 0 ) {
943  const tripoint_abs_omt city_center_omt = project_to<coords::omt>( nearest_city.abs_sm_pos );
944  // Very necessary little hack: We look for roads around our start, and path from the closest. Because the most common start(evac shelter) cannot be pathed through...
945  const tripoint_abs_omt nearest_road = overmap_buffer.find_closest( omtstart, "road", 3, false );
946  // Reveal route to closest city and a 3 tile radius around the route
947  overmap_buffer.reveal_route( nearest_road, city_center_omt, 3 );
948  // Reveal destination city (scaling with city size setting)
949  overmap_buffer.reveal( city_center_omt, city_size );
950  }
951 
952  u.set_moves( 0 );
953  u.process_turn(); // process_turn adds the initial move points
957  u.next_climate_control_check = calendar::before_time_starts; // Force recheck at startup
958  u.last_climate_control_ret = false;
959 
960  //Reset character safe mode/pickup rules
965 
966  // spawn the starting NPC, assuming it's not disallowed by the scenario
967  if( !get_scenario()->has_flag( "LONE_START" ) ) {
969  }
970  //Load NPCs. Set nearby npcs to active.
971  load_npcs();
972  // Spawn the monsters
973  // Surrounded start ones
974  std::vector<std::pair<mongroup_id, float>> surround_groups = get_scenario()->surround_groups();
975  const bool surrounded_start_scenario = !surround_groups.empty();
976  const bool surrounded_start_options = get_option<bool>( "BLACK_ROAD" );
977  if( surrounded_start_options && !surrounded_start_scenario ) {
978  surround_groups.emplace_back( GROUP_BLACK_ROAD, 70.0f );
979  }
980  const bool spawn_near = surrounded_start_options || surrounded_start_scenario;
981  if( spawn_near ) {
982  for( const std::pair<mongroup_id, float> &sg : surround_groups ) {
983  start_loc.surround_with_monsters( omtstart, sg.first, sg.second );
984  }
985  }
986 
987  m.spawn_monsters( !spawn_near ); // Static monsters
988 
989  // Make sure that no monsters are near the player
990  // This can happen in lab starts
991  if( !spawn_near ) {
992  for( monster &critter : all_monsters() ) {
993  if( rl_dist( critter.pos(), u.pos() ) <= 5 ||
994  m.clear_path( critter.pos(), u.pos(), 40, 1, 100 ) ) {
995  remove_zombie( critter );
996  }
997  }
998  }
999 
1000  //Create mutation_category_level
1002  //Calculate mutation drench protection stats
1003  u.drench_mut_calc();
1004  if( scen->has_flag( "FIRE_START" ) ) {
1005  start_loc.burn( omtstart, 3, 3 );
1006  }
1007  if( scen->has_flag( "HELI_CRASH" ) ) {
1008  start_loc.handle_heli_crash( u );
1009  bool success = false;
1010  for( wrapped_vehicle v : m.get_vehicles() ) {
1011  std::string name = v.v->type.str();
1012  std::string search = std::string( "helicopter" );
1013  if( name.find( search ) != std::string::npos ) {
1014  for( const vpart_reference &vp : v.v->get_any_parts( VPFLAG_CONTROLS ) ) {
1015  const tripoint pos = vp.pos();
1016  u.setpos( pos );
1017 
1018  // Delete the items that would have spawned here from a "corpse"
1019  for( const int sp : v.v->parts_at_relative( vp.mount(), true ) ) {
1020  vpart_reference( *v.v, sp ).items().clear();
1021  }
1022 
1023  auto mons = critter_tracker->find( u.get_location() );
1024  if( mons != nullptr ) {
1025  critter_tracker->remove( *mons );
1026  }
1027 
1028  success = true;
1029  break;
1030  }
1031  if( success ) {
1032  v.v->name = "Bird Wreckage";
1033  break;
1034  }
1035  }
1036  }
1037  }
1038  if( scen->has_flag( "BORDERED" ) ) {
1040  point_abs_om om;
1041  point_om_omt omt;
1042  std::tie( om, omt ) = project_remain<coords::om>( p_player );
1043 
1044  // The Wall is supposed to be a 100x100 rectangle centered on player,
1045  // but if player is spawned next to edges of the overmap we need to make it smaller so it doesn't overlap the overmap's borders
1046  int left_x = omt.x() < 50 ? 1 : omt.x() - 50;
1047  int right_x = omt.x() > 129 ? 179 : omt.x() + 50;
1048  int up_y = omt.y() < 50 ? 1 : omt.y() - 50;
1049  int down_y = omt.y() > 129 ? 179 : omt.y() + 50;
1050 
1051  overmap &starting_om = get_cur_om();
1052 
1053  for( int x = left_x; x <= right_x; x++ ) {
1054  for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1055  starting_om.place_special_forced( overmap_special_world, { x, up_y, z },
1057  }
1058  }
1059 
1060  for( int x = left_x; x <= right_x; x++ ) {
1061  for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1062  starting_om.place_special_forced( overmap_special_world, { x, down_y, z },
1064  }
1065  }
1066 
1067  for( int y = up_y; y <= down_y; y++ ) {
1068  for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1069  starting_om.place_special_forced( overmap_special_world, { left_x, y, z },
1071  }
1072  }
1073 
1074  for( int y = up_y; y <= down_y; y++ ) {
1075  for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1076  starting_om.place_special_forced( overmap_special_world, { right_x, y, z },
1078  }
1079  }
1080  }
1081  for( item *&e : u.inv_dump() ) {
1082  e->set_owner( get_player_character() );
1083  }
1084  // Now that we're done handling coordinates, ensure the player's submap is in the center of the map
1085  update_map( u );
1086  // Profession pets
1087  for( const mtype_id &elem : u.starting_pets ) {
1088  if( monster *const mon = place_critter_around( elem, u.pos(), 5 ) ) {
1089  mon->friendly = -1;
1090  mon->add_effect( effect_pet, 1_turns, true );
1091  } else {
1092  add_msg_debug( debugmode::DF_GAME, "cannot place starting pet, no space!" );
1093  }
1094  }
1095  if( u.starting_vehicle &&
1097  std::vector<std::string> {} ) ) {
1098  debugmsg( "could not place starting vehicle" );
1099  }
1100  // Assign all of this scenario's missions to the player.
1101  for( const mission_type_id &m : scen->missions() ) {
1102  mission *new_mission = mission::reserve_new( m, character_id() );
1103  new_mission->assign( u );
1104  }
1105 
1106  // Same for profession missions
1107  if( !!u.prof ) {
1108  for( const mission_type_id &m : u.prof->missions() ) {
1109  mission *new_mission = mission::reserve_new( m, character_id() );
1110  new_mission->assign( u );
1111  }
1112  }
1113  // ... and for hobbies
1114  for( const profession *hby : u.hobbies ) {
1115  if( !!hby ) {
1116  for( const mission_type_id &m : hby->missions() ) {
1117  mission *new_mission = mission::reserve_new( m, character_id() );
1118  new_mission->assign( u );
1119  }
1120  }
1121  }
1122 
1124  get_event_bus().send<event_type::game_avatar_new>( /*is_new_game=*/true, /*is_debug=*/false,
1125  u.getID(), u.name, u.male, u.prof->ident(), u.custom_profession );
1126  time_played_at_last_load = std::chrono::seconds( 0 );
1127  time_of_last_load = std::chrono::steady_clock::now();
1129  const oter_id &cur_ter = overmap_buffer.ter( abs_omt );
1130  get_event_bus().send<event_type::avatar_enters_omt>( abs_omt.raw(), cur_ter );
1131 
1133  return true;
1134 }
bool last_climate_control_ret
Definition: character.h:4101
void process_turn() override
Handles end-of-turn processing.
Definition: character.cpp:2309
std::set< const profession * > hobbies
Definition: character.h:589
std::optional< city > starting_city
Definition: character.h:594
void drench_mut_calc()
Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats)
Definition: character.cpp:7675
void set_stamina(int new_stamina)
Definition: character.cpp:6836
void calc_mutation_levels()
Recalculates mutation_category_level[] values for the player.
Definition: character.cpp:7638
time_point next_climate_control_check
Definition: character.h:4100
std::string custom_profession
Definition: character.h:1119
void migrate_items_to_storage(bool disintegrate)
used for profession spawning and save migration for nested containers.
Definition: character.cpp:9078
std::optional< point_abs_om > world_origin
Definition: character.h:595
const profession * prof
Definition: character.h:588
bool random_start_location
Definition: character.h:596
start_location_id start_location
Definition: character.h:597
void default_initialize()
Perform default initialization.
Definition: auto_note.cpp:160
vproto_id starting_vehicle
Definition: avatar.h:377
void add_profession_items()
std::vector< mtype_id > starting_pets
Definition: avatar.h:378
void start_calendar()
Definition: game.cpp:13102
void create_starting_npcs()
Definition: game.cpp:1277
overmap & get_cur_om() const
The overmap which contains the center submap of the reality bubble.
Definition: game.cpp:13111
vehicle * place_vehicle_nearby(const vproto_id &id, const point_abs_omt &origin, int min_distance, int max_distance, const std::vector< std::string > &omt_search_types={})
Definition: game.cpp:1136
friend const scenario * get_scenario()
Definition: game.cpp:13842
virtual void clear()
Definition: item_stack.cpp:24
bool clear_path(const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
Check whether there's a direct line of sight between F and T with the additional movecost restraints.
Definition: map.cpp:7748
VehicleList get_vehicles()
Definition: map.cpp:432
static mission * reserve_new(const mission_type_id &type, const character_id &npc_id)
Create a new mission of the given type and assign it to the given npc.
Definition: mission.cpp:79
void assign(avatar &u)
Assigns the mission to the player.
Definition: mission.cpp:301
void place_special_forced(const overmap_special_id &special_id, const tripoint_om_omt &p, om_direction::type dir)
Definition: overmap.cpp:3990
bool reveal(const point_abs_omt &center, int radius, int z)
Mark a square area around center on Z-level z as seen.
tripoint_abs_omt find_closest(const tripoint_abs_omt &origin, const omt_find_params &params)
Returns the closest point of terrain type.
bool reveal_route(const tripoint_abs_omt &source, const tripoint_abs_omt &dest, int radius=0, bool road_only=false)
city_reference closest_city(const tripoint_abs_sm &center)
Find the closest city.
const string_id< profession > & ident() const
Definition: profession.cpp:475
const std::vector< mission_type_id > & missions() const
Definition: profession.cpp:921
void clear_character_rules()
bool has_map_extra() const
Definition: scenario.cpp:676
const std::vector< mission_type_id > & missions() const
Definition: scenario.cpp:684
const std::vector< std::pair< mongroup_id, float > > & surround_groups() const
Definition: scenario.cpp:692
const map_extra_id & get_map_extra() const
Definition: scenario.cpp:680
start_location_id random_start_location() const
Definition: scenario.cpp:335
bool has_flag(const std::string &flag) const
Such as a seasonal start, fiery start, surrounded start, etc.
Definition: scenario.cpp:634
void handle_heli_crash(avatar &you) const
void burn(const tripoint_abs_omt &omtstart, size_t count, int rad) const
Burn random terrain / furniture with FLAMMABLE or FLAMMABLE_ASH tag.
void surround_with_monsters(const tripoint_abs_omt &omtstart, const mongroup_id &type, float expected_points) const
Adds surround start monsters.
void add_map_extra(const tripoint_abs_omt &omtstart, const map_extra_id &map_extra) const
Adds a map extra, see map_extras.h and map_extras.cpp.
void prepare_map(const tripoint_abs_omt &omtstart) const
Initialize the map at players start location using prepare_map.
void set_parameters(const tripoint_abs_omt &omtstart, const std::unordered_map< std::string, std::string > &parameters_to_set) const
Set any parameters assigned to the chosen start location.
void place_player(avatar &you, const tripoint_abs_omt &omtstart) const
Place the player somewhere in the reality bubble (g->m).
std::pair< tripoint_abs_omt, std::unordered_map< std::string, std::string > > find_player_initial_location(const point_abs_om &origin) const
Find a suitable start location on the overmap.
vehicle_stack items() const
Definition: vehicle.cpp:7791
units::temperature temperature
Definition: weather.h:206
static const mongroup_id GROUP_BLACK_ROAD("GROUP_BLACK_ROAD")
static const overmap_special_id overmap_special_world("world")
constexpr units::temperature SPRING_TEMPERATURE
Base starting spring temperature in Kelvin used for climate, weather and temperature calculation.
void update_weather()
Definition: weather.cpp:902
void load_new_character(Character &you)
Sets up the initial queue for a new character.
static bool search(const ui_adaptor &om_ui, tripoint_abs_omt &curs, const tripoint_abs_omt &orig)
unsigned int rng_bits()
Definition: rng.cpp:11
tripoint_abs_sm abs_sm_pos
The global absolute position of the city (in submap coordinates!)
Definition: overmapbuffer.h:77
static const std::vector< city > & get_all()
Definition: city.cpp:64
@ VPFLAG_CONTROLS
Definition: veh_type.h:69

References _, city_reference::abs_sm_pos, start_location::add_map_extra(), add_msg_debug, avatar::add_profession_items(), all_monsters(), mission::assign(), assign_npc_id(), avatar_enters_omt, calendar::before_time_starts, map::build_map_cache(), start_location::burn(), Character::calc_mutation_levels(), character_id, auto_notes::auto_note_settings::clear(), item_stack::clear(), mapbuffer::clear(), overmapbuffer::clear(), auto_pickup::player_settings::clear_character_rules(), safemode::clear_character_rules(), map::clear_path(), overmapbuffer::closest_city(), create_starting_npcs(), critter_tracker, Character::custom_profession, debugmsg, auto_notes::auto_note_settings::default_initialize(), debugmode::DF_GAME, Character::drench_mut_calc(), effect_pet, overmapbuffer::find_closest(), start_location::find_player_initial_location(), game_avatar_new, game_start, gamemode, map::get_abs_sub(), city::get_all(), get_auto_notes_settings(), get_auto_pickup(), get_cur_om(), get_event_bus, Creature::get_location(), scenario::get_map_extra(), get_player_character, get_safemode(), get_scenario, Character::get_stamina_max(), map::get_vehicles(), Character::getID(), map::getlocal(), getVersionString(), Creature::global_omt_location(), GROUP_BLACK_ROAD, HALF_MAPSIZE, start_location::handle_heli_crash(), scenario::has_flag(), scenario::has_map_extra(), Character::hobbies, profession::ident(), init_autosave(), Character::inv_dump(), overmap::invalid_tripoint, map::invalidate_map_cache(), vpart_reference::items(), Character::last_climate_control_ret, safemode::load_global(), load_map(), load_master(), effect_on_conditions::load_new_character(), load_npcs(), m, Character::male, MAPBUFFER, Character::migrate_items_to_storage(), profession::missions(), scenario::missions(), mostseen, Character::name, om_direction::name(), new_game, Character::next_climate_control_check, weather_manager::nextweather, om_direction::north, string_id< T >::obj(), coords::om, omt, overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, overmap_special_world, place_critter_around(), start_location::place_player(), overmap::place_special_forced(), place_vehicle_nearby(), point, popup(), Creature::pos(), math_opers::pos(), start_location::prepare_map(), Character::process_turn(), Character::prof, query_yn(), random_entry(), Character::random_start_location, scenario::random_start_location(), coords::coord_point_mut< Point, Subpoint, InBounds >::raw(), ui_manager::redraw(), refresh_display(), remove_zombie(), mission::reserve_new(), cata::hash64_detail::ret, overmapbuffer::reveal(), overmapbuffer::reveal_route(), rl_dist(), rng_bits(), safe_mode, SAFE_MODE_OFF, SAFE_MODE_ON, scen, overmap_ui::search(), seed, event_bus::send(), Creature::set_moves(), start_location::set_parameters(), Character::set_stamina(), Character::setID(), Creature::setpos(), map::spawn_monsters(), SPRING_TEMPERATURE, start_calendar(), Character::start_location, Character::starting_city, avatar::starting_pets, avatar::starting_vehicle, scenario::surround_groups(), start_location::surround_with_monsters(), weather_manager::temperature, overmapbuffer::ter(), time_of_last_load, time_played_at_last_load, calendar::turn, u, update_map(), weather_manager::update_weather(), VPFLAG_CONTROLS, weather, Character::world_origin, coords::coord_point< Point, Origin, Scale, InBounds >::xy(), and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

◆ start_hauling()

void game::start_hauling ( const tripoint pos)

Definition at line 12339 of file game.cpp.

12340 {
12341  std::vector<item_location> candidate_items = m.get_haulable_items( pos );
12342  // Find target items and quantities thereof for the new activity
12343  u.trim_haul_list( candidate_items );
12344  std::vector<item_location> target_items = u.haul_list;
12345 
12346  if( u.is_autohauling() && !u.suppress_autohaul ) {
12347  for( const item_location &item : u.haul_list ) {
12348  candidate_items.erase( std::remove( candidate_items.begin(), candidate_items.end(), item ),
12349  candidate_items.end() );
12350  }
12351  if( u.hauling_filter.empty() ) {
12352  target_items.insert( target_items.end(), candidate_items.begin(), candidate_items.end() );
12353  } else {
12354  std::function<bool( const item & )> filter = item_filter_from_string( u.hauling_filter );
12355  std::copy_if( candidate_items.begin(), candidate_items.end(), std::back_inserter( target_items ),
12356  [&filter]( const item_location & item ) {
12357  return filter( *item );
12358  } );
12359  }
12360  }
12361 
12362  u.suppress_autohaul = false;
12363  u.haul_list.clear();
12364 
12365  // Quantity of 0 means move all
12366  const std::vector<int> quantities( target_items.size(), 0 );
12367 
12368  if( target_items.empty() ) {
12369  // Nothing to haul
12370  if( !u.is_autohauling() ) {
12371  u.stop_hauling();
12372  }
12373  return;
12374  }
12375 
12376  // Whether the destination is inside a vehicle (not supported)
12377  const bool to_vehicle = false;
12378  // Destination relative to the player
12379  const tripoint relative_destination{};
12380 
12381  const move_items_activity_actor actor( target_items, quantities, to_vehicle, relative_destination,
12382  true );
12383  u.assign_activity( actor );
12384 }
std::string hauling_filter
Definition: character.h:2701
bool is_autohauling() const
Definition: character.cpp:8894
bool trim_haul_list(const std::vector< item_location > &valid_items)
Definition: character.cpp:8899
std::vector< item_location > haul_list
Definition: character.h:2703
bool suppress_autohaul
Definition: character.h:2700
std::vector< item_location > get_haulable_items(const tripoint &pos)
Definition: map.cpp:10536
std::function< bool(const item &)> item_filter_from_string(const std::string &filter)
Get a function that returns true if the item matches the query.

References Character::assign_activity(), filter, map::get_haulable_items(), Character::haul_list, Character::hauling_filter, Character::is_autohauling(), item_filter_from_string(), m, math_opers::pos(), Character::stop_hauling(), Character::suppress_autohaul, Character::trim_haul_list(), and u.

Referenced by vertical_move(), and walk_move().

◆ stats()

stats_tracker & game::stats ( )

Definition at line 3427 of file game.cpp.

3428 {
3429  return *stats_tracker_ptr;
3430 }

References stats_tracker_ptr.

Referenced by death_screen(), load(), and setup().

◆ swap_critters()

bool game::swap_critters ( Creature a,
Creature b 
)

Swaps positions of two creatures.

Definition at line 5435 of file game.cpp.

5436 {
5437  if( &a == &b ) {
5438  // No need to do anything, but print a debugmsg anyway
5439  debugmsg( "Tried to swap %s with itself", a.disp_name() );
5440  return true;
5441  }
5442  creature_tracker &creatures = get_creature_tracker();
5443  if( creatures.creature_at( a.pos() ) != &a ) {
5444  debugmsg( "Tried to swap when it would cause a collision between %s and %s.",
5445  b.disp_name(), creatures.creature_at( a.pos() )->disp_name() );
5446  return false;
5447  }
5448  if( creatures.creature_at( b.pos() ) != &b ) {
5449  debugmsg( "Tried to swap when it would cause a collision between %s and %s.",
5450  a.disp_name(), creatures.creature_at( b.pos() )->disp_name() );
5451  return false;
5452  }
5453  // Simplify by "sorting" the arguments
5454  // Only the first argument can be u
5455  // If swapping player/npc with a monster, monster is second
5456  bool a_first = a.is_avatar() ||
5457  ( a.is_npc() && !b.is_avatar() );
5458  Creature &first = a_first ? a : b;
5459  Creature &second = a_first ? b : a;
5460  // Possible options:
5461  // both first and second are monsters
5462  // second is a monster, first is a player or an npc
5463  // first is a player, second is an npc
5464  // both first and second are npcs
5465  if( first.is_monster() ) {
5466  monster *m1 = dynamic_cast< monster * >( &first );
5467  monster *m2 = dynamic_cast< monster * >( &second );
5468  if( m1 == nullptr || m2 == nullptr || m1 == m2 ) {
5469  debugmsg( "Couldn't swap two monsters" );
5470  return false;
5471  }
5472 
5473  critter_tracker->swap_positions( *m1, *m2 );
5474  return true;
5475  }
5476 
5477  Character *u_or_npc = dynamic_cast< Character * >( &first );
5478  Character *other_npc = dynamic_cast< Character * >( &second );
5479 
5480  if( u_or_npc->in_vehicle ) {
5481  m.unboard_vehicle( u_or_npc->pos() );
5482  }
5483 
5484  if( other_npc && other_npc->in_vehicle ) {
5485  m.unboard_vehicle( other_npc->pos() );
5486  }
5487 
5488  tripoint temp = second.pos();
5489  second.setpos( first.pos() );
5490 
5491  if( first.is_avatar() ) {
5492  walk_move( temp );
5493  } else {
5494  first.setpos( temp );
5495  if( m.veh_at( u_or_npc->pos() ).part_with_feature( VPFLAG_BOARDABLE, true ) ) {
5496  m.board_vehicle( u_or_npc->pos(), u_or_npc );
5497  }
5498  }
5499 
5500  if( other_npc && m.veh_at( other_npc->pos() ).part_with_feature( VPFLAG_BOARDABLE, true ) ) {
5501  m.board_vehicle( other_npc->pos(), other_npc );
5502  }
5503  return true;
5504 }
bool walk_move(const tripoint &dest, bool via_ramp=false, bool furniture_move=false)
Definition: game.cpp:10533
@ VPFLAG_BOARDABLE
Definition: veh_type.h:67

References a, b, map::board_vehicle(), creature_tracker::creature_at(), critter_tracker, debugmsg, get_creature_tracker, Character::in_vehicle, Creature::is_avatar(), Creature::is_monster(), m, optional_vpart_position::part_with_feature(), Creature::pos(), second, Creature::setpos(), temp, map::unboard_vehicle(), map::veh_at(), VPFLAG_BOARDABLE, and walk_move().

Referenced by npc_menu().

◆ take_screenshot() [1/2]

bool game::take_screenshot ( ) const

Saves a screenshot of the current viewport, as a PNG file.

Filesystem location is derived from the current world and character.

Note
: Only works for SDL/TILES (otherwise the function returns false). A window (more precisely, a viewport) must already exist and the SDL renderer must be valid.
Returns
true if the screenshot generation was successful, false otherwise.

Definition at line 8270 of file game.cpp.

8271 {
8272  popup( _( "This binary was not compiled with tiles support." ) );
8273  return false;
8274 }

References _, and popup().

◆ take_screenshot() [2/2]

bool game::take_screenshot ( const std::string &  file_path) const

Saves a screenshot of the current viewport, as a PNG file, to the given location.

Parameters
file_pathA full path to the file where the screenshot should be saved.
Note
: Only works for SDL/TILES (otherwise the function returns false). A window (more precisely, a viewport) must already exist and the SDL renderer must be valid.
Returns
true if the screenshot generation was successful, false otherwise.

Definition at line 8265 of file game.cpp.

8266 {
8267  return false;
8268 }

◆ temp_exit_fullscreen()

void game::temp_exit_fullscreen ( )

Definition at line 742 of file game.cpp.

743 {
744  if( fullscreen ) {
745  was_fullscreen = true;
747  } else {
748  was_fullscreen = false;
749  }
750 }

References fullscreen, toggle_fullscreen(), and was_fullscreen.

Referenced by look_around().

◆ toggle_debug_hour_timer()

void game::toggle_debug_hour_timer ( )

Definition at line 12970 of file game.cpp.

12971 {
12973 }
class game::debug_hour_timer debug_hour_timer

References game::debug_hour_timer::toggle().

Referenced by do_regular_action(), and look_around().

◆ toggle_fullscreen()

void game::toggle_fullscreen ( )

Definition at line 654 of file game.cpp.

655 {
656 #if !defined(TILES)
659 #else
660  toggle_fullscreen_window();
661 #endif
662 }

References fullscreen, and mark_main_ui_adaptor_resize().

Referenced by do_regular_action(), reenter_fullscreen(), and temp_exit_fullscreen().

◆ toggle_language_to_en()

void game::toggle_language_to_en ( )

Definition at line 675 of file game.cpp.

676 {
677  // No-op if we aren't complied with localization
678 #if defined(LOCALIZE)
679  const std::string english = "en" ;
680  static std::string secondary_lang = english;
681  std::string current_lang = TranslationManager::GetInstance().GetCurrentLanguage();
682  secondary_lang = current_lang != english ? current_lang : secondary_lang;
683  std::string new_lang = current_lang != english ? english : secondary_lang;
684  set_language( new_lang );
685 #endif
686 }
void set_language(const std::string &lang)

References set_language().

◆ toggle_pixel_minimap()

void game::toggle_pixel_minimap ( ) const

Definition at line 664 of file game.cpp.

665 {
666 #if defined(TILES)
667  if( pixel_minimap_option ) {
668  clear_window_area( w_pixel_minimap );
669  }
672 #endif // TILES
673 }

References mark_main_ui_adaptor_resize(), pixel_minimap_option, and w_pixel_minimap.

Referenced by do_regular_action(), and look_around().

◆ try_get_left_click_action()

bool game::try_get_left_click_action ( action_id act,
const tripoint_bub_ms mouse_target 
)
private

Definition at line 2655 of file game.cpp.

2656 {
2657  bool new_destination = true;
2658  if( !destination_preview.empty() ) {
2659  auto &final_destination = destination_preview.back();
2660  if( final_destination.xy() == mouse_target.xy() ) {
2661  // Second click
2662  new_destination = false;
2664  destination_preview.clear();
2666  if( act == ACTION_NULL ) {
2667  // Something went wrong
2668  u.clear_destination();
2669  return false;
2670  }
2671  }
2672  }
2673 
2674  if( new_destination ) {
2675  const std::optional<std::vector<tripoint_bub_ms>> try_route =
2676  safe_route_to( u, mouse_target, 0, []( const std::string & msg ) {
2677  add_msg( msg );
2678  } );
2679  if( try_route.has_value() ) {
2680  destination_preview = *try_route;
2681  return true;
2682  }
2683  return false;
2684  }
2685 
2686  return true;
2687 }

References act, ACTION_NULL, add_msg(), Character::clear_destination(), destination_preview, Character::get_next_auto_move_direction(), safe_route_to(), Character::set_destination(), u, and coords::coord_point< Point, Origin, Scale, InBounds >::xy().

Referenced by handle_action().

◆ try_get_right_click_action()

bool game::try_get_right_click_action ( action_id act,
const tripoint_bub_ms mouse_target 
)
private

Definition at line 2689 of file game.cpp.

2690 {
2691  const bool cleared_destination = !destination_preview.empty();
2692  u.clear_destination();
2693  destination_preview.clear();
2694 
2695  if( cleared_destination ) {
2696  // Produce no-op if auto move had just been cleared on this action
2697  // e.g. from a previous single left mouse click. This has the effect
2698  // of right-click canceling an auto move before it is initiated.
2699  return false;
2700  }
2701 
2702  const bool is_adjacent = square_dist( mouse_target.xy(), u.pos_bub().xy() ) <= 1;
2703  const bool is_self = square_dist( mouse_target.xy(), u.pos_bub().xy() ) <= 0;
2704  if( const monster *const mon = get_creature_tracker().creature_at<monster>( mouse_target ) ) {
2705  if( !u.sees( *mon ) ) {
2706  add_msg( _( "Nothing relevant here." ) );
2707  return false;
2708  }
2709 
2710  if( !u.get_wielded_item() || !u.get_wielded_item()->is_gun() ) {
2711  add_msg( m_info, _( "You are not wielding a ranged weapon." ) );
2712  return false;
2713  }
2714 
2715  // TODO: Add weapon range check. This requires weapon to be reloaded.
2716 
2717  act = ACTION_FIRE;
2718  } else if( is_adjacent &&
2719  m.close_door( tripoint_bub_ms( mouse_target.xy(), u.posz() ),
2720  !m.is_outside( u.pos() ), true ) ) {
2721  act = ACTION_CLOSE;
2722  } else if( is_self ) {
2723  act = ACTION_PICKUP;
2724  } else if( is_adjacent ) {
2725  act = ACTION_EXAMINE;
2726  } else {
2727  add_msg( _( "Nothing relevant here." ) );
2728  return false;
2729  }
2730 
2731  return true;
2732 }
bool close_door(const tripoint &p, bool inside, bool check_only)
Definition: map.cpp:4818

References _, act, ACTION_CLOSE, ACTION_EXAMINE, ACTION_FIRE, ACTION_PICKUP, add_msg(), Character::clear_destination(), map::close_door(), destination_preview, get_creature_tracker, Character::get_wielded_item(), item::is_gun(), map::is_outside(), m, m_info, Creature::pos(), Creature::pos_bub(), Creature::posz(), Character::sees(), square_dist(), u, and coords::coord_point< Point, Origin, Scale, InBounds >::xy().

Referenced by handle_action().

◆ unique_npc_despawn()

void game::unique_npc_despawn ( const std::string &  id)

Definition at line 3462 of file game.cpp.

3463 {
3464  unique_npcs.erase( id );
3465 }

References unique_npcs.

◆ unique_npc_exists()

bool game::unique_npc_exists ( const std::string &  id)

Definition at line 3457 of file game.cpp.

3458 {
3459  return unique_npcs.count( id ) > 0;
3460 }

References unique_npcs.

Referenced by get_unique_npc_location().

◆ unload_container()

void game::unload_container ( )
private

Definition at line 9329 of file game.cpp.

9330 {
9331  if( const std::optional<tripoint> pnt = choose_adjacent( _( "Unload where?" ) ) ) {
9333  }
9334 }
drop_locations unload_container(avatar &you)

References _, choose_adjacent(), Character::drop(), u, and game_menus::inv::unload_container().

Referenced by do_regular_action().

◆ unload_npcs()

void game::unload_npcs ( )
private

Unloads all NPCs.

If you call this you must later call load_npcs, lest caches get rather confused. The tests used to call this a lot when they shouldn't. It is now private to reduce the chance of similar problems in the future.

Definition at line 1243 of file game.cpp.

1244 {
1245  for( const auto &npc : critter_tracker->active_npc ) {
1246  npc->on_unload();
1247  }
1248 
1249  critter_tracker->clear_npcs();
1250 }
void on_unload()
Do some cleanup and caching as npc is being unloaded from map.
Definition: npc.cpp:3057

References critter_tracker, and npc::on_unload().

Referenced by place_player_overmap(), and reload_npcs().

◆ unserialize()

void game::unserialize ( std::istream &  fin,
const cata_path path 
)

Definition at line 205 of file savegame.cpp.

206 {
207  size_t json_file_offset = chkversion( fin );
208  int tmpturn = 0;
209  int tmpcalstart = 0;
210  int tmprun = 0;
211  tripoint_om_sm lev;
212  point_abs_om com;
213  JsonValue jsin = json_loader::from_path_at_offset( path, json_file_offset );
214  try {
215  JsonObject data = jsin.get_object();
216 
217  data.read( "turn", tmpturn );
218  data.read( "calendar_start", tmpcalstart );
219  calendar::initial_season = static_cast<season_type>( data.get_int( "initial_season",
220  static_cast<int>( SPRING ) ) );
221 
222  data.read( "auto_travel_mode", auto_travel_mode );
223  data.read( "run_mode", tmprun );
224  data.read( "mostseen", mostseen );
225  data.read( "levx", lev.x() );
226  data.read( "levy", lev.y() );
227  data.read( "levz", lev.z() );
228  data.read( "om_x", com.x() );
229  data.read( "om_y", com.y() );
230 
231  data.read( "view_offset_x", u.view_offset.x );
232  data.read( "view_offset_y", u.view_offset.y );
233  data.read( "view_offset_z", u.view_offset.z );
234 
235  calendar::turn = time_point( tmpturn );
236  calendar::start_of_cataclysm = time_point( tmpcalstart );
237 
238  if( !data.read( "game_start", calendar::start_of_game ) ) {
240  }
241 
242  load_map( project_combine( com, lev ), /*pump_events=*/true );
243 
244  safe_mode = static_cast<safe_mode_type>( tmprun );
245  if( get_option<bool>( "SAFEMODE" ) && safe_mode == SAFE_MODE_OFF ) {
247  }
248 
249  std::string linebuff;
250  std::string linebuf;
251  if( data.read( "grscent", linebuf ) && data.read( "typescent", linebuff ) ) {
252  scent.deserialize( linebuf );
253  scent.deserialize( linebuff, true );
254  } else {
255  scent.reset();
256  }
257  data.read( "active_monsters", *critter_tracker );
258 
259  data.has_null( "stair_monsters" ); // TEMPORARY until 0.G
260  data.has_null( "monstairz" ); // TEMPORARY until 0.G
261 
262  data.read( "driving_view_offset", driving_view_offset );
263  data.read( "turnssincelastmon", turnssincelastmon );
264  data.read( "bVMonsterLookFire", bVMonsterLookFire );
265 
266  data.read( "kill_tracker", *kill_tracker_ptr );
267 
268  data.read( "player", u );
269  data.read( "inactive_global_effect_on_condition_vector",
271  //load queued_eocs
272  for( JsonObject elem : data.get_array( "queued_global_effect_on_conditions" ) ) {
274  temp.time = time_point( elem.get_int( "time" ) );
275  temp.eoc = effect_on_condition_id( elem.get_string( "eoc" ) );
276  std::unordered_map<std::string, std::string> context;
277  for( const JsonMember &jm : elem.get_object( "context" ) ) {
278  context[jm.name()] = jm.get_string();
279  }
280  temp.context = context;
282  }
284  data.read( "unique_npcs", unique_npcs );
286  data.read( "stats_tracker", *stats_tracker_ptr );
287  data.read( "achievements_tracker", *achievements_tracker_ptr );
289  Messages::deserialize( data );
290 
291  } catch( const JsonError &jsonerr ) {
292  debugmsg( "Bad save json\n%s", jsonerr.c_str() );
293  return;
294  }
295 }
@ SPRING
Definition: calendar.h:22
int get_int(std::string_view key) const
bool read(std::string_view name, T &t, bool throw_on_error=true) const
JsonArray get_array(std::string_view key) const
bool has_null(std::string_view key) const
void unserialize(JsonObject &jo)
Definition: savegame.cpp:1491
static JsonValue from_path_at_offset(const cata_path &source_file, size_t offset=0) noexcept(false)
void deserialize(const std::string &data, bool is_type=false)
Definition: savegame.cpp:297
safe_mode_type
Definition: game.h:61
void deserialize(const JsonObject &json)
Definition: messages.cpp:443
auto project_combine(const coord_point< PointL, CoarseOrigin, CoarseScale, CoarseInBounds > &coarse, const coord_point< PointR, FineOrigin, FineScale, FineInBounds > &fine)
Definition: coordinates.h:633
static size_t chkversion(std::istream &fin)
Definition: savegame.cpp:185
void push(const queued_eoc &eoc)
Definition: character.h:359
string_id< effect_on_condition > effect_on_condition_id
Definition: type_id.h:59

References achievements_tracker_ptr, auto_travel_mode, bVMonsterLookFire, JsonError::c_str(), chkversion(), context, critter_tracker, debugmsg, Messages::deserialize(), scent_map::deserialize(), driving_view_offset, json_loader::from_path_at_offset(), JsonObject::get_array(), JsonObject::get_int(), JsonValue::get_object(), global_variables_instance, JsonObject::has_null(), inactive_global_effect_on_condition_vector, calendar::initial_season, inp_mngr, kill_tracker_ptr, load_map(), mostseen, coords::project_combine(), input_manager::pump_events(), queued_eocs::push(), queued_global_effect_on_conditions, JsonObject::read(), scent_map::reset(), safe_mode, SAFE_MODE_OFF, SAFE_MODE_ON, scent, SPRING, calendar::start_of_cataclysm, calendar::start_of_game, stats_tracker_ptr, temp, calendar::turn, turnssincelastmon, u, unique_npcs, global_variables::unserialize(), Character::view_offset, coords::coord_point_mut< Point, Subpoint, InBounds >::x(), tripoint::x, coords::coord_point_mut< Point, Subpoint, InBounds >::y(), tripoint::y, coords::coord_point_mut< Point, Subpoint, InBounds >::z(), and tripoint::z.

Referenced by load().

◆ unserialize_master() [1/2]

void game::unserialize_master ( const cata_path file_name,
std::istream &  fin 
)

Definition at line 1408 of file savegame.cpp.

1409 {
1411  size_t json_offset = chkversion( fin );
1412  try {
1413  JsonValue jv = json_loader::from_path_at_offset( file_name, json_offset );
1414  unserialize_master( jv );
1415  } catch( const JsonError &e ) {
1416  debugmsg( "error loading %s: %s", SAVE_MASTER, e.c_str() );
1417  }
1418 }
int savegame_loading_version
Definition: savegame.cpp:78

References JsonError::c_str(), chkversion(), debugmsg, json_loader::from_path_at_offset(), SAVE_MASTER(), and savegame_loading_version.

Referenced by load_master().

◆ unserialize_master() [2/2]

void game::unserialize_master ( const JsonValue jv)

Definition at line 1420 of file savegame.cpp.

1421 {
1422  JsonObject game_json = jv;
1423  for( JsonMember jsin : game_json ) {
1424  std::string name = jsin.name();
1425  if( name == "next_mission_id" ) {
1426  next_mission_id = jsin.get_int();
1427  } else if( name == "next_npc_id" ) {
1428  next_npc_id.deserialize( jsin );
1429  } else if( name == "active_missions" ) {
1430  mission::unserialize_all( jsin );
1431  } else if( name == "factions" ) {
1432  jsin.read( *faction_manager_ptr );
1433  } else if( name == "seed" ) {
1434  jsin.read( seed );
1435  } else if( name == "weather" ) {
1437  } else if( name == "timed_events" ) {
1439  } else if( name == "overmapbuffer" ) {
1441  } else if( name == "placed_unique_specials" ) {
1443  }
1444  }
1445 }
void deserialize(int)
static void unserialize_all(const JsonArray &ja)
Definition: savegame.cpp:1399
void deserialize_overmap_global_state(const JsonObject &json)
Reads metadata about special placement from JSON.
Definition: savegame.cpp:1713
void deserialize_placed_unique_specials(const JsonValue &jsin)
Reads deprecated placed unique specials data, replaced by overmap_global_state.
Definition: savegame.cpp:1725
static void unserialize_all(const JsonArray &ja)
Definition: savegame.cpp:1504
static void unserialize_all(const JsonObject &w)
Definition: savegame.cpp:1472

References character_id::deserialize(), overmapbuffer::deserialize_overmap_global_state(), overmapbuffer::deserialize_placed_unique_specials(), faction_manager_ptr, JsonValue::get_int(), om_direction::name(), next_mission_id, next_npc_id, overmap_buffer, JsonValue::read(), seed, mission::unserialize_all(), timed_event_manager::unserialize_all(), and weather_manager::unserialize_all().

◆ update_map() [1/2]

point game::update_map ( Character p,
bool  z_level_changed = false 
)

Definition at line 12615 of file game.cpp.

12616 {
12617  point p2( p.posx(), p.posy() );
12618  return update_map( p2.x, p2.y, z_level_changed );
12619 }

References Creature::posx(), Creature::posy(), point::x, and point::y.

Referenced by fling_creature(), load(), place_player(), start_game(), and vertical_move().

◆ update_map() [2/2]

point game::update_map ( int &  x,
int &  y,
bool  z_level_changed = false 
)

Definition at line 12621 of file game.cpp.

12622 {
12623  point shift;
12624 
12625  while( x < HALF_MAPSIZE_X ) {
12626  x += SEEX;
12627  shift.x--;
12628  }
12629  while( x >= HALF_MAPSIZE_X + SEEX ) {
12630  x -= SEEX;
12631  shift.x++;
12632  }
12633  while( y < HALF_MAPSIZE_Y ) {
12634  y += SEEY;
12635  shift.y--;
12636  }
12637  while( y >= HALF_MAPSIZE_Y + SEEY ) {
12638  y -= SEEY;
12639  shift.y++;
12640  }
12641 
12642  if( shift == point_zero ) {
12643  // adjust player position
12644  u.setpos( tripoint( x, y, m.get_abs_sub().z() ) );
12645  if( z_level_changed ) {
12646  // Update what parts of the world map we can see
12647  // We may be able to see farther now that the z-level has changed.
12649  }
12650  // Not actually shifting the submaps, all the stuff below would do nothing
12651  return point_zero;
12652  }
12653 
12654  // this handles loading/unloading submaps that have scrolled on or off the viewport
12655  // NOLINTNEXTLINE(cata-use-named-point-constants)
12656  inclusive_rectangle<point> size_1( point( -1, -1 ), point( 1, 1 ) );
12657  point remaining_shift = shift;
12658  while( remaining_shift != point_zero ) {
12659  point this_shift = clamp( remaining_shift, size_1 );
12660  m.shift( this_shift );
12661  remaining_shift -= this_shift;
12662  }
12663 
12664  // Shift monsters
12665  shift_monsters( tripoint( shift, 0 ) );
12666  const point shift_ms = sm_to_ms_copy( shift );
12667  u.shift_destination( -shift_ms );
12668 
12669  // Shift NPCs
12670  for( auto it = critter_tracker->active_npc.begin(); it != critter_tracker->active_npc.end(); ) {
12671  ( *it )->shift( shift );
12672  if( ( *it )->posx() < 0 || ( *it )->posx() >= MAPSIZE_X ||
12673  ( *it )->posy() < 0 || ( *it )->posy() >= MAPSIZE_Y ) {
12674  //Remove the npc from the active list. It remains in the overmap list.
12675  ( *it )->on_unload();
12676  it = critter_tracker->active_npc.erase( it );
12677  } else {
12678  it++;
12679  }
12680  }
12681 
12682  scent.shift( shift_ms );
12683 
12684  // Also ensure the player is on current z-level
12685  // m.get_abs_sub().z should later be removed, when there is no longer such a thing
12686  // as "current z-level"
12687  u.setpos( tripoint( x, y, m.get_abs_sub().z() ) );
12688 
12689  // Only do the loading after all coordinates have been shifted.
12690 
12691  // Check for overmap saved npcs that should now come into view.
12692  // Put those in the active list.
12693  load_npcs();
12694 
12695  // Make sure map cache is consistent since it may have shifted.
12696  for( int zlev = -OVERMAP_DEPTH; zlev <= OVERMAP_HEIGHT; ++zlev ) {
12697  m.invalidate_map_cache( zlev );
12698  }
12699  m.build_map_cache( m.get_abs_sub().z() );
12700 
12701  // Spawn monsters if appropriate
12702  // This call will generate new monsters in addition to loading, so it's placed after NPC loading
12703  m.spawn_monsters( false ); // Static monsters
12704 
12705  // Update what parts of the world map we can see
12707 
12708  return shift;
12709 }
void shift_destination(const point &shift)
void shift_monsters(const tripoint &shift)
Shift all active monsters, the shift vector is the number of shifted submaps.
Definition: game.cpp:12776
void shift(const point &s)
Shift the map along the vector s.
Definition: map.cpp:8008
void shift(const point &sm_shift)
Definition: scent_map.cpp:83
point sm_to_ms_copy(const point &p)
constexpr int HALF_MAPSIZE_Y
constexpr int HALF_MAPSIZE_X

References map::build_map_cache(), clamp(), critter_tracker, map::get_abs_sub(), HALF_MAPSIZE_X, HALF_MAPSIZE_Y, map::invalidate_map_cache(), load_npcs(), m, MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, point, point_zero, scent, SEEX, SEEY, Creature::setpos(), shift, map::shift(), scent_map::shift(), Character::shift_destination(), shift_monsters(), sm_to_ms_copy(), map::spawn_monsters(), tripoint, u, update_overmap_seen(), and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

◆ update_overmap_seen()

void game::update_overmap_seen ( )

Definition at line 12711 of file game.cpp.

12712 {
12713  const tripoint_abs_omt ompos = u.global_omt_location();
12714  const int dist = u.overmap_sight_range( light_level( u.posz() ) );
12715  const int dist_squared = dist * dist;
12716  // We can always see where we're standing
12717  overmap_buffer.set_seen( ompos, true );
12718  for( const tripoint_abs_omt &p : points_in_radius( ompos, dist ) ) {
12719  const point_rel_omt delta = p.xy() - ompos.xy();
12720  const int h_squared = delta.x() * delta.x() + delta.y() * delta.y();
12721  if( trigdist && h_squared > dist_squared ) {
12722  continue;
12723  }
12724  if( delta == point_rel_omt() ) {
12725  // 1. This case is already handled outside of the loop
12726  // 2. Calculating multiplier would cause division by zero
12727  continue;
12728  }
12729  // If circular distances are enabled, scale overmap distances by the diagonality of the sight line.
12730  point abs_delta = delta.raw().abs();
12731  int max_delta = std::max( abs_delta.x, abs_delta.y );
12732  const float multiplier = trigdist ? std::sqrt( h_squared ) / max_delta : 1;
12733  const std::vector<tripoint_abs_omt> line = line_to( ompos, p );
12734  float sight_points = dist;
12735  for( auto it = line.begin();
12736  it != line.end() && sight_points >= 0; ++it ) {
12737  const oter_id &ter = overmap_buffer.ter( *it );
12738  sight_points -= static_cast<int>( ter->get_see_cost() ) * multiplier;
12739  }
12740  if( sight_points >= 0 ) {
12741  tripoint_abs_omt seen( p );
12742  do {
12743  overmap_buffer.set_seen( seen, true );
12744  --seen.z();
12745  } while( seen.z() >= 0 );
12746  }
12747  }
12748 }
void set_seen(const tripoint_abs_omt &p, bool seen=true)
coords::coord_point< point, coords::origin::relative, coords::omt > point_rel_omt
Definition: coordinates.h:704
bool trigdist
Definition: line.cpp:18
unsigned char get_see_cost() const
Definition: omdata.h:359

References oter_t::get_see_cost(), Creature::global_omt_location(), light_level(), line, line_to(), max(), overmap_buffer, Character::overmap_sight_range(), points_in_radius(), Creature::posz(), coords::coord_point_mut< Point, Subpoint, InBounds >::raw(), overmapbuffer::set_seen(), sqrt(), overmapbuffer::ter(), trigdist, u, coords::coord_point_mut< Point, Subpoint, InBounds >::x(), point::x, coords::coord_point< Point, Origin, Scale, InBounds >::xy(), coords::coord_point_mut< Point, Subpoint, InBounds >::y(), point::y, and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

Referenced by place_player_overmap(), and update_map().

◆ update_unique_npc_location()

void game::update_unique_npc_location ( const std::string &  id,
point_abs_om  loc 
)

Definition at line 3442 of file game.cpp.

3443 {
3444  unique_npcs[id] = loc;
3445 }

References base_camps::id, and unique_npcs.

◆ update_zombie_pos()

bool game::update_zombie_pos ( const monster critter,
const tripoint_abs_ms old_pos,
const tripoint_abs_ms new_pos 
)

Redirects to the creature_tracker update_pos() function.

Definition at line 5279 of file game.cpp.

5281 {
5282  return critter_tracker->update_pos( critter, old_pos, new_pos );
5283 }

References critter_tracker.

◆ use_computer()

void game::use_computer ( const tripoint p)

Checks to see if a player can use a computer (not illiterate, etc.) and uses if able.

Definition at line 5084 of file game.cpp.

5085 {
5086  if( u.has_trait( trait_ILLITERATE ) ) {
5087  add_msg( m_info, _( "You can not read a computer screen!" ) );
5088  return;
5089  }
5090  if( u.is_blind() ) {
5091  // we don't have screen readers in game
5092  add_msg( m_info, _( "You can not see a computer screen!" ) );
5093  return;
5094  }
5097  !u.has_flag( STATIC( json_character_flag( "ENHANCED_VISION" ) ) ) ) {
5098  add_msg( m_info, _( "You'll need to put on reading glasses before you can see the screen." ) );
5099  return;
5100  }
5101 
5102  computer *used = m.computer_at( p );
5103 
5104  if( used == nullptr ) {
5105  if( m.has_flag( ter_furn_flag::TFLAG_CONSOLE, p ) ) { //Console without map data
5106  add_msg( m_bad, _( "The console doesn't display anything coherent." ) );
5107  } else {
5108  dbg( D_ERROR ) << "game:use_computer: Tried to use computer at (" <<
5109  p.x << ", " << p.y << ", " << p.z << ") - none there";
5110  debugmsg( "Tried to use computer at (%d, %d, %d) - none there", p.x, p.y, p.z );
5111  }
5112  return;
5113  }
5114  if( used->eocs.empty() ) {
5115  computer_session( *used ).use();
5116  } else {
5117  dialogue d( get_talker_for( get_avatar() ), get_talker_for( used ) );
5118  for( const effect_on_condition_id &eoc : used->eocs ) {
5119  eoc->activate( d );
5120  }
5121  }
5122 }
void use()
Handles player use of a computer.
std::vector< effect_on_condition_id > eocs
Definition: computer.h:160
computer * computer_at(const tripoint &p)
Definition: map.cpp:6745
const flag_id flag_FIX_FARSIGHT("FIX_FARSIGHT")
static const efftype_id effect_transition_contacts("transition_contacts")
static const efftype_id effect_contacts("contacts")
static const json_character_flag json_flag_HYPEROPIC("HYPEROPIC")
#define STATIC(expr)
The purpose of this macro is to provide a concise syntax for creation of inline literals (std::string...
Definition: make_static.h:31
string_id< json_flag > json_character_flag
Definition: type_id.h:316

References _, add_msg(), map::computer_at(), D_ERROR, dbg, debugmsg, effect_contacts, effect_transition_contacts, eoc, computer::eocs, flag_FIX_FARSIGHT, get_avatar, get_talker_for(), Creature::has_effect(), Character::has_flag(), map::has_flag(), Character::has_trait(), Character::is_blind(), json_flag_HYPEROPIC, m, m_bad, m_info, STATIC, TFLAG_CONSOLE, trait_ILLITERATE, u, computer_session::use(), Character::worn_with_flag(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by examine().

◆ validate_camps()

void game::validate_camps ( )

validate camps to ensure they are on the overmap list

Definition at line 1803 of file game.cpp.

1804 {
1805  basecamp camp = m.hoist_submap_camp( u.pos() );
1806  if( camp.is_valid() ) {
1807  overmap_buffer.add_camp( camp );
1808  m.remove_submap_camp( u.pos() );
1809  } else if( camp.camp_omt_pos() != tripoint_abs_omt() ) {
1810  std::string camp_name = _( "Faction Camp" );
1811  camp.set_name( camp_name );
1812  overmap_buffer.add_camp( camp );
1813  m.remove_submap_camp( u.pos() );
1814  }
1815 }
bool is_valid() const
Definition: basecamp.h:166
void set_name(const std::string &new_name)
Definition: basecamp.cpp:636
tripoint_abs_omt camp_omt_pos() const
Definition: basecamp.h:175
basecamp hoist_submap_camp(const tripoint &p)
Definition: map.cpp:6785
void remove_submap_camp(const tripoint &)
Definition: map.cpp:6775
void add_camp(const basecamp &camp)
Add Basecamp to overmapbuffer.

References _, overmapbuffer::add_camp(), basecamp::camp_omt_pos(), map::hoist_submap_camp(), basecamp::is_valid(), m, overmap_buffer, Creature::pos(), map::remove_submap_camp(), basecamp::set_name(), and u.

Referenced by load().

◆ validate_linked_vehicles()

void game::validate_linked_vehicles ( )

validate towed vehicles so they get linked up again after a load

Definition at line 1745 of file game.cpp.

1746 {
1747  for( wrapped_vehicle &veh : m.get_vehicles() ) {
1748  vehicle *v = veh.v;
1751  if( other_v ) {
1752  // the other vehicle is towing us.
1753  v->tow_data.set_towing( other_v, v );
1755  }
1756  }
1757  }
1758 }
tripoint other_towing_point
Definition: vehicle.h:214
bool set_towing(vehicle *tower_veh, vehicle *towed_veh)
Definition: vehicle.cpp:6816
towing_data tow_data
Definition: vehicle.h:2308

References map::get_vehicles(), m, towing_data::other_towing_point, towing_data::set_towing(), vehicle::tow_data, tripoint_zero, map::veh_at(), and veh_pointer_or_null().

Referenced by load().

◆ validate_mounted_npcs()

void game::validate_mounted_npcs ( )

Definition at line 1760 of file game.cpp.

1761 {
1762  for( monster &m : all_monsters() ) {
1763  if( m.has_effect( effect_ridden ) && m.mounted_player_id.is_valid() ) {
1764  Character *mounted_pl = g->critter_by_id<Character>( m.mounted_player_id );
1765  if( !mounted_pl ) {
1766  // Target no longer valid.
1767  m.mounted_player_id = character_id();
1768  m.remove_effect( effect_ridden );
1769  continue;
1770  }
1771  mounted_pl->mounted_creature = shared_from( m );
1772  mounted_pl->setpos( m.pos() );
1773  mounted_pl->add_effect( effect_riding, 1_turns, true );
1774  m.mounted_player = mounted_pl;
1775  }
1776  }
1777 }

References Creature::add_effect(), all_monsters(), character_id, effect_ridden, effect_riding, g, m, Character::mounted_creature, Creature::setpos(), and shared_from().

Referenced by load().

◆ validate_npc_followers()

void game::validate_npc_followers ( )

validate list of followers to account for overmap buffers

Definition at line 1779 of file game.cpp.

1780 {
1781  // Make sure visible followers are in the list.
1782  const std::vector<npc *> visible_followers = get_npcs_if( [&]( const npc & guy ) {
1783  return guy.is_player_ally();
1784  } );
1785  for( npc *guy : visible_followers ) {
1786  update_faction_api( guy );
1787  add_npc_follower( guy->getID() );
1788  }
1789  // Make sure overmapbuffered NPC followers are in the list.
1790  for( const auto &temp_guy : overmap_buffer.get_npcs_near_player( 300 ) ) {
1791  npc *guy = temp_guy.get();
1792  if( guy->is_player_ally() ) {
1793  update_faction_api( guy );
1794  add_npc_follower( guy->getID() );
1795  }
1796  }
1797  // Make sure that serialized player followers sync up with game list
1798  for( const character_id &temp_id : u.follower_ids ) {
1799  add_npc_follower( temp_id );
1800  }
1801 }
void add_npc_follower(const character_id &id)
Add follower id to set of followers.
Definition: game.cpp:1725
static void update_faction_api(npc *guy)
Definition: game.cpp:1737

References add_npc_follower(), avatar::follower_ids, get_npcs_if(), overmapbuffer::get_npcs_near_player(), Character::getID(), npc::is_player_ally(), overmap_buffer, u, and update_faction_api().

Referenced by load().

◆ vertical_move()

void game::vertical_move ( int  z,
bool  force,
bool  peeking = false 
)

Moves the player vertically.

If force == true then they are falling. If peeking == true, forbids some exotic movement options

Definition at line 11966 of file game.cpp.

11967 {
11968  if( u.is_mounted() ) {
11969  monster *mons = u.mounted_creature.get();
11970  if( mons->has_flag( mon_flag_RIDEABLE_MECH ) ) {
11971  if( !mons->check_mech_powered() ) {
11972  add_msg( m_bad, _( "Your %s refuses to move as its batteries have been drained." ),
11973  mons->get_name() );
11974  return;
11975  }
11976  }
11977  }
11978 
11979  map &here = get_map();
11980 
11981  // Force means we're going down, even if there's no staircase, etc.
11982  bool climbing = false;
11984  int move_cost = 100;
11985  tripoint stairs( u.posx(), u.posy(), u.posz() + movez );
11986  bool wall_cling = u.has_flag( json_flag_WALL_CLING );
11987  bool adjacent_climb = false;
11988  if( !force && movez == 1 && !here.has_flag( ter_furn_flag::TFLAG_GOES_UP, u.pos() ) &&
11989  !u.is_underwater() ) {
11990  // Climbing
11991  for( const tripoint &p : here.points_in_radius( u.pos(), 2 ) ) {
11993  adjacent_climb = true;
11994  }
11995  }
11996  if( here.has_floor_or_support( stairs ) ) {
11997  add_msg( m_info, _( "You can't climb here - there's a ceiling above your head." ) );
11998  return;
11999  }
12000 
12001  if( u.get_working_arm_count() < 1 && !here.has_flag( ter_furn_flag::TFLAG_LADDER, u.pos() ) ) {
12002  add_msg( m_info, _( "You can't climb because your arms are too damaged or encumbered." ) );
12003  return;
12004  }
12005 
12006  const int cost = u.climbing_cost( u.pos(), stairs );
12007  add_msg_debug( debugmode::DF_GAME, "Climb cost %d", cost );
12008  const bool can_climb_here = cost > 0 ||
12009  u.has_flag( json_flag_CLIMB_NO_LADDER ) || wall_cling;
12010  if( !can_climb_here && !adjacent_climb ) {
12011  add_msg( m_info, _( "You can't climb here - you need walls and/or furniture to brace against." ) );
12012  return;
12013  }
12014 
12015  const item_location weapon = u.get_wielded_item();
12016  if( !here.has_flag( ter_furn_flag::TFLAG_LADDER, u.pos() ) && weapon &&
12017  weapon->is_two_handed( u ) ) {
12018  if( query_yn(
12019  _( "You can't climb because you have to wield a %s with both hands.\n\nPut it away?" ),
12020  weapon->tname() ) ) {
12021  if( !u.unwield() ) {
12022  return;
12023  }
12024  } else {
12025  return;
12026  }
12027  }
12028 
12029  std::vector<tripoint> pts;
12030  for( const tripoint &pt : here.points_in_radius( stairs, 1 ) ) {
12031  if( here.passable( pt ) &&
12032  here.has_floor_or_support( pt ) ) {
12033  pts.push_back( pt );
12034  }
12035  }
12036 
12037  if( wall_cling && here.is_wall_adjacent( stairs ) ) {
12038  pts.push_back( stairs );
12039  }
12040 
12041  if( pts.empty() ) {
12042  add_msg( m_info,
12043  _( "You can't climb here - there is no terrain above you that would support your weight." ) );
12044  return;
12045  } else {
12046  // TODO: Make it an extended action
12047  climbing = true;
12050  move_cost = cost == 0 ? 1000 : cost + 500;
12051 
12052  const std::optional<tripoint> pnt = point_selection_menu( pts );
12053  if( !pnt ) {
12054  return;
12055  }
12056  stairs = *pnt;
12057  }
12058  }
12059 
12060  if( !force && movez == -1 && !here.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, u.pos() ) &&
12062  !u.has_effect( effect_gliding ) ) {
12063  if( wall_cling && !here.has_floor_or_support( u.pos() ) ) {
12064  climbing = true;
12067  u.burn_energy_all( -750 );
12068  move_cost += 500;
12069  } else {
12070  add_msg( m_info, _( "You can't go down here!" ) );
12071  return;
12072  }
12073  } else if( !climbing && !force && movez == 1 &&
12075  add_msg( m_info, _( "You can't go up here!" ) );
12076  return;
12077  }
12078 
12079  if( force ) {
12080  // Let go of a grabbed cart.
12082  } else if( u.grab_point != tripoint_zero ) {
12083  add_msg( m_info, _( "You can't drag things up and down stairs." ) );
12084  return;
12085  }
12086 
12087  // TODO: Use u.posz() instead of m.abs_sub
12088  const int z_after = m.get_abs_sub().z() + movez;
12089  if( z_after < -OVERMAP_DEPTH ) {
12090  add_msg( m_info, _( "Halfway down, the way down becomes blocked off." ) );
12091  return;
12092  } else if( z_after > OVERMAP_HEIGHT ) {
12093  add_msg( m_info, _( "Halfway up, the way up becomes blocked off." ) );
12094  return;
12095  }
12096 
12097  if( !u.move_effects( false ) && !force ) {
12098  // move_effects determined we could not move, waste all moves
12099  u.set_moves( 0 );
12100  return;
12101  }
12102 
12103  if( climbing &&
12104  slip_down( ( ( movez > 1 ) ? climb_maneuver::up : climb_maneuver::down ), climbing_aid ) ) {
12105  return;
12106  }
12107 
12108  bool swimming = false;
12109  bool surfacing = false;
12110  bool submerging = false;
12111  // > and < are used for diving underwater.
12112  if( here.has_flag( ter_furn_flag::TFLAG_SWIMMABLE, u.pos() ) ) {
12113  swimming = true;
12114  const ter_id &target_ter = here.ter( u.pos() + tripoint( 0, 0, movez ) );
12115 
12116  // If we're in a water tile that has both air above and deep enough water to submerge in...
12117  if( here.has_flag( ter_furn_flag::TFLAG_DEEP_WATER, u.pos() ) &&
12119  // ...and we're trying to swim down
12120  if( movez == -1 ) {
12121  // ...and we're already submerged
12122  if( u.is_underwater() ) {
12123  // ...and there's more water beneath us.
12124  if( target_ter->has_flag( ter_furn_flag::TFLAG_WATER_CUBE ) ) {
12125  // Then go ahead and move down.
12126  add_msg( _( "You swim down." ) );
12127  } else {
12128  // There's no more water beneath us.
12129  add_msg( m_info,
12130  _( "You are already underwater and there is no more water beneath you to swim down!" ) );
12131  return;
12132  }
12133  }
12134  // ...and we're not already submerged.
12135  else {
12136  // Check for a flotation device first before allowing us to submerge.
12137  if( u.worn_with_flag( flag_FLOTATION ) ) {
12138  add_msg( m_info, _( "You can't dive while wearing a flotation device." ) );
12139  return;
12140  }
12141 
12142  // Then dive under the surface.
12143  u.set_underwater( true );
12144  add_msg( _( "You dive underwater!" ) );
12145  submerging = true;
12146  }
12147  }
12148  // ...and we're trying to surface
12149  else if( movez == 1 ) {
12150  // ... and we're already submerged
12151  if( u.is_underwater() ) {
12152  if( u.swim_speed() < 500 || u.shoe_type_count( itype_swim_fins ) ) {
12153  u.set_underwater( false );
12154  add_msg( _( "You surface." ) );
12155  surfacing = true;
12156  } else {
12157  add_msg( m_info, _( "You try to surface but can't!" ) );
12158  return;
12159  }
12160  }
12161  }
12162  }
12163  // If we're in a water tile that is entirely water
12164  else if( here.has_flag( ter_furn_flag::TFLAG_WATER_CUBE, u.pos() ) ) {
12165  // If you're at this point, you should already be underwater, but force that to be the case.
12166  if( !u.is_underwater() ) {
12167  u.set_underwater( true );
12168  }
12169 
12170  // ...and we're trying to swim down
12171  if( movez == -1 ) {
12172  // ...and there's more water beneath us.
12173  if( target_ter->has_flag( ter_furn_flag::TFLAG_WATER_CUBE ) ) {
12174  // Then go ahead and move down.
12175  add_msg( _( "You swim down." ) );
12176  } else {
12177  add_msg( m_info,
12178  _( "You are already underwater and there is no more water beneath you to swim down!" ) );
12179  return;
12180  }
12181  }
12182  // ...and we're trying to move up
12183  else if( movez == 1 ) {
12184  // ...and there's more water above us us.
12185  if( target_ter->has_flag( ter_furn_flag::TFLAG_WATER_CUBE ) ||
12186  target_ter->has_flag( ter_furn_flag::TFLAG_DEEP_WATER ) ) {
12187  // Then go ahead and move up.
12188  add_msg( _( "You swim up." ) );
12189  } else {
12190  add_msg( m_info, _( "You are already underwater and there is no water above you to swim up!" ) );
12191  return;
12192  }
12193  }
12194  }
12195  }
12196 
12197  // Find the corresponding staircase
12198  bool rope_ladder = false;
12199  // TODO: Remove the stairfinding, make the mapgen gen aligned maps
12200  if( !force && !climbing && !swimming ) {
12201  const std::optional<tripoint> pnt = find_or_make_stairs( m, z_after, rope_ladder, peeking,
12202  u.pos() );
12203  if( !pnt ) {
12204  return;
12205  }
12206  stairs = *pnt;
12207  }
12208 
12209  std::vector<monster *> monsters_following;
12210  if( std::abs( movez ) == 1 ) {
12211  bool ladder = here.has_flag( ter_furn_flag::TFLAG_DIFFICULT_Z, u.pos() );
12212  for( monster &critter : all_monsters() ) {
12213  if( ladder && !critter.climbs() ) {
12214  continue;
12215  }
12216  // TODO: just check if it's going for the avatar's location, it's simpler
12217  Creature *target = critter.attack_target();
12218  if( ( target && target->is_avatar() ) || ( !critter.has_effect( effect_ridden ) &&
12219  ( critter.is_pet_follow() || critter.has_effect( effect_led_by_leash ) ) &&
12220  !critter.has_effect( effect_tied ) && critter.sees( u ) ) ) {
12221  monsters_following.push_back( &critter );
12222  }
12223  }
12224  }
12225 
12226  if( u.is_mounted() ) {
12227  monster *crit = u.mounted_creature.get();
12228  if( crit->has_flag( mon_flag_RIDEABLE_MECH ) ) {
12230  }
12231  } else {
12232  u.mod_moves( -move_cost );
12234  }
12235 
12236  if( surfacing || submerging ) {
12237  // Surfacing and submerging don't actually move us anywhere, and just
12238  // toggle our underwater state in the same location.
12239  return;
12240  }
12241 
12242  const tripoint old_pos = u.pos();
12243  const tripoint old_abs_pos = here.getabs( old_pos );
12244  point submap_shift;
12245  const bool z_level_changed = vertical_shift( z_after );
12246  if( !force ) {
12247  submap_shift = update_map( stairs.x, stairs.y, z_level_changed );
12248  }
12249 
12250  // if an NPC or monster is on the stairs when player ascends/descends
12251  // they may end up merged on the same tile, do some displacement to resolve that.
12252  creature_tracker &creatures = get_creature_tracker();
12253  if( creatures.creature_at<npc>( u.pos(), true ) ||
12254  creatures.creature_at<monster>( u.pos(), true ) ) {
12255  std::string crit_name;
12256  bool player_displace = false;
12257  std::optional<tripoint> displace = find_empty_spot_nearby( u.pos() );
12258  if( !displace.has_value() ) {
12259  // They can always move to the previous location of the player.
12260  displace = old_pos;
12261  }
12262  npc *guy = creatures.creature_at<npc>( u.pos(), true );
12263  if( guy ) {
12264  crit_name = guy->get_name();
12265  tripoint old_pos = guy->pos();
12266  if( !guy->is_enemy() ) {
12267  guy->move_away_from( u.pos(), true );
12268  if( old_pos != guy->pos() ) {
12269  add_msg( _( "%s moves out of the way for you." ), guy->get_name() );
12270  }
12271  } else {
12272  player_displace = true;
12273  }
12274  }
12275  monster *mon = creatures.creature_at<monster>( u.pos(), true );
12276  // if the monster is ridden by the player or an NPC:
12277  // Dont displace them. If they are mounted by a friendly NPC,
12278  // then the NPC will already have been displaced just above.
12279  // if they are ridden by the player, we want them to coexist on same tile
12280  if( mon && !mon->mounted_player ) {
12281  crit_name = mon->get_name();
12282  if( mon->friendly == -1 ) {
12283  mon->setpos( *displace );
12284  add_msg( _( "Your %s moves out of the way for you." ), mon->get_name() );
12285  } else {
12286  player_displace = true;
12287  }
12288  }
12289  if( player_displace ) {
12290  u.setpos( *displace );
12291  u.mod_moves( -to_moves<int>( 1_seconds ) * 0.2 );;
12292  add_msg( _( "You push past %s blocking the way." ), crit_name );
12293  }
12294  }
12295 
12296  // Now that we know the player's destination position, we can move their mount as well
12297  if( u.is_mounted() ) {
12298  u.mounted_creature->setpos( u.pos() );
12299  }
12300 
12301  // This ugly check is here because of stair teleport bullshit
12302  // TODO: Remove stair teleport bullshit
12303  if( rl_dist( u.pos(), old_pos ) <= 1 ) {
12304  for( monster *m : monsters_following ) {
12305  m->set_dest( u.get_location() );
12306  }
12307  }
12308 
12309  if( rope_ladder ) {
12310  if( u.has_flag( json_flag_WEB_RAPPEL ) ) {
12311  here.furn_set( u.pos(), furn_f_web_up );
12312  } else {
12313  here.furn_set( u.pos(), furn_f_rope_up );
12314  }
12315  }
12316 
12317  if( here.ter( stairs ) == ter_t_manhole_cover ) {
12318  here.spawn_item( stairs + point( rng( -1, 1 ), rng( -1, 1 ) ), itype_manhole_cover );
12319  here.ter_set( stairs, ter_t_manhole );
12320  }
12321 
12322  if( u.is_hauling() ) {
12323  const tripoint adjusted_pos = old_pos - sm_to_ms_copy( submap_shift );
12324  start_hauling( adjusted_pos );
12325  }
12326 
12327  here.invalidate_map_cache( here.get_abs_sub().z() );
12328  // Upon force movement, traps can not be avoided.
12329  if( !wall_cling && ( get_map().tr_at( u.pos() ) == tr_ledge &&
12330  !u.has_effect( effect_gliding ) ) ) {
12331  here.creature_on_trap( u, !force );
12332  }
12333 
12334  u.recoil = MAX_RECOIL;
12335 
12336  cata_event_dispatch::avatar_moves( old_abs_pos, u, m );
12337 }
int get_working_arm_count() const
Definition: character.cpp:2101
move_mode_id current_movement_mode() const
Definition: character.cpp:2159
int swim_speed() const
Returns the player's movecost for swimming across water tiles.
Definition: character.cpp:1416
bool unwield()
Definition: character.cpp:7899
int shoe_type_count(const itype_id &it) const
Returns 1 if the player is wearing an item of that count on one foot, 2 if on both,...
virtual bool is_underwater() const
Definition: creature.cpp:292
void start_hauling(const tripoint &pos)
Definition: game.cpp:12339
bool slip_down(climb_maneuver maneuver, climbing_aid_id aid=climbing_aid_id::NULL_ID(), bool show_chance_messages=true)
Checks if player is able to successfully climb to/from some terrain and not slip down.
Definition: game.cpp:13417
std::optional< tripoint > find_or_make_stairs(map &mp, int z_after, bool &rope_ladder, bool peeking, const tripoint &pos)
Returns the other end of the stairs (if any).
Definition: game.cpp:12386
bool is_two_handed(const Character &guy) const
Whether the character needs both hands to wield this item.
Definition: item.cpp:9137
bool is_wall_adjacent(const tripoint &center) const
Definition: map.cpp:2409
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0, const std::set< flag_id > &flags={}, const std::string &variant="", const std::string &faction="")
Definition: map.cpp:5100
bool check_mech_powered() const
Definition: monster.cpp:2975
units::energy use_mech_power(units::energy amt)
Consume UPS from mech battery.
Definition: monster.cpp:2959
Character * mounted_player
Definition: monster.h:526
units::energy mech_power_use() const
Definition: move_mode.cpp:184
tripoint displace(cube_direction d)
Definition: overmap.cpp:1161
const flag_id flag_FLOTATION("FLOTATION")
static const efftype_id effect_tied("tied")
static const furn_str_id furn_f_rope_up("f_rope_up")
static const itype_id itype_manhole_cover("manhole_cover")
static const furn_str_id furn_f_web_up("f_web_up")
static std::optional< tripoint > find_empty_spot_nearby(const tripoint &pos)
Definition: game.cpp:11947
static const ter_str_id ter_t_manhole("t_manhole")
static const json_character_flag json_flag_CLIMB_NO_LADDER("CLIMB_NO_LADDER")
static const json_character_flag json_flag_WALL_CLING("WALL_CLING")
static const itype_id itype_swim_fins("swim_fins")
static const climbing_aid_id climbing_aid_ability_WALL_CLING("ability_WALL_CLING")
static const efftype_id effect_led_by_leash("led_by_leash")
static const climbing_aid_id climbing_aid_furn_CLIMBABLE("furn_CLIMBABLE")
constexpr float EXTRA_EXERCISE
void avatar_moves(const tripoint &old_abs_pos, const avatar &u, const map &m)
Definition: game.cpp:13758

References _, abs(), add_msg(), add_msg_debug, all_monsters(), cata_event_dispatch::avatar_moves(), Character::burn_energy_all(), monster::check_mech_powered(), climbing_aid_ability_WALL_CLING, climbing_aid_default, climbing_aid_furn_CLIMBABLE, Character::climbing_cost(), creature_tracker::creature_at(), map::creature_on_trap(), Character::current_movement_mode(), debugmode::DF_GAME, displace(), down, effect_gliding, effect_led_by_leash, effect_ridden, effect_tied, EXTRA_EXERCISE, find_empty_spot_nearby(), find_or_make_stairs(), flag_FLOTATION, force, monster::friendly, furn_f_rope_up, furn_f_web_up, map::furn_set(), map::get_abs_sub(), get_creature_tracker, Creature::get_location(), get_map, Character::get_name(), monster::get_name(), Character::get_wielded_item(), Character::get_working_arm_count(), map::getabs(), avatar::grab(), Character::grab_point, Creature::has_effect(), Character::has_flag(), monster::has_flag(), map_data_common_t::has_flag(), map::has_flag(), map::has_floor_or_support(), map::invalidate_map_cache(), Creature::is_avatar(), npc::is_enemy(), Character::is_hauling(), Character::is_mounted(), item::is_two_handed(), Creature::is_underwater(), map::is_wall_adjacent(), itype_manhole_cover, itype_swim_fins, json_flag_CLIMB_NO_LADDER, json_flag_WALL_CLING, json_flag_WEB_RAPPEL, m, m_bad, m_info, MAX_RECOIL, move_mode::mech_power_use(), Creature::mod_moves(), mon_flag_RIDEABLE_MECH, Character::mounted_creature, monster::mounted_player, npc::move_away_from(), move_cost, Character::move_effects(), NONE, OVERMAP_DEPTH, OVERMAP_HEIGHT, map::passable(), point, point_selection_menu(), map::points_in_radius(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), query_yn(), Character::recoil, rl_dist(), rng(), Character::set_activity_level(), Creature::set_moves(), Character::set_underwater(), Creature::setpos(), Character::shoe_type_count(), slip_down(), sm_to_ms_copy(), map::spawn_item(), start_hauling(), Character::swim_speed(), map::ter(), map::ter_set(), ter_t_manhole, ter_t_manhole_cover, TFLAG_CLIMB_ADJACENT, TFLAG_DEEP_WATER, TFLAG_DIFFICULT_Z, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_LADDER, TFLAG_NO_FLOOR_WATER, TFLAG_SWIMMABLE, TFLAG_WATER_CUBE, item::tname(), tr_ledge, tripoint_zero, u, Character::unwield(), up, update_map(), monster::use_mech_power(), vertical_shift(), Character::worn_with_flag(), tripoint::x, tripoint::y, and coords::coord_point_mut< Point, Subpoint, InBounds >::z().

Referenced by do_regular_action(), and peek().

◆ vertical_notes()

void game::vertical_notes ( int  z_before,
int  z_after 
)

Add goes up/down auto_notes (if turned on)

Definition at line 12575 of file game.cpp.

12576 {
12577  if( z_before == z_after || !get_option<bool>( "AUTO_NOTES" ) ||
12578  !get_option<bool>( "AUTO_NOTES_STAIRS" ) ) {
12579  return;
12580  }
12581 
12582  if( !m.inbounds_z( z_before ) || !m.inbounds_z( z_after ) ) {
12583  debugmsg( "game::vertical_notes invalid arguments: z_before == %d, z_after == %d",
12584  z_before, z_after );
12585  return;
12586  }
12587  // Figure out where we know there are up/down connectors
12588  // Fill in all the tiles we know about (e.g. subway stations)
12589  static const int REVEAL_RADIUS = 40;
12590  for( const tripoint_abs_omt &p : points_in_radius( u.global_omt_location(), REVEAL_RADIUS ) ) {
12591  const tripoint_abs_omt cursp_before( p.xy(), z_before );
12592  const tripoint_abs_omt cursp_after( p.xy(), z_after );
12593 
12594  if( !overmap_buffer.seen( cursp_before ) ) {
12595  continue;
12596  }
12597  if( overmap_buffer.has_note( cursp_after ) ) {
12598  // Already has a note -> never add an AUTO-note
12599  continue;
12600  }
12601  const oter_id &ter = overmap_buffer.ter( cursp_before );
12602  const oter_id &ter2 = overmap_buffer.ter( cursp_after );
12603  if( z_after > z_before && ter->has_flag( oter_flags::known_up ) &&
12604  !ter2->has_flag( oter_flags::known_down ) ) {
12605  overmap_buffer.set_seen( cursp_after, true );
12606  overmap_buffer.add_note( cursp_after, string_format( ">:W;%s", _( "AUTO: goes down" ) ) );
12607  } else if( z_after < z_before && ter->has_flag( oter_flags::known_down ) &&
12608  !ter2->has_flag( oter_flags::known_up ) ) {
12609  overmap_buffer.set_seen( cursp_after, true );
12610  overmap_buffer.add_note( cursp_after, string_format( "<:W;%s", _( "AUTO: goes up" ) ) );
12611  }
12612  }
12613 }
bool inbounds_z(const int z) const
Definition: map.h:1901
void add_note(const tripoint_abs_omt &, const std::string &message)
bool has_flag(oter_flags flag) const
Definition: omdata.h:395

References _, overmapbuffer::add_note(), debugmsg, Creature::global_omt_location(), oter_t::has_flag(), overmapbuffer::has_note(), map::inbounds_z(), known_down, known_up, m, overmap_buffer, points_in_radius(), overmapbuffer::seen(), overmapbuffer::set_seen(), string_format(), overmapbuffer::ter(), and u.

Referenced by vertical_shift().

◆ vertical_shift()

bool game::vertical_shift ( int  z_after)

Actual z-level movement part of vertical_move.

Doesn't include stair finding, traps etc. Returns true if the z-level changed.

Definition at line 12554 of file game.cpp.

12555 {
12556  if( z_after < -OVERMAP_DEPTH || z_after > OVERMAP_HEIGHT ) {
12557  debugmsg( "Tried to get z-level %d outside allowed range of %d-%d",
12558  z_after, -OVERMAP_DEPTH, OVERMAP_HEIGHT );
12559  return false;
12560  }
12561 
12562  scent.reset();
12563 
12564  const int z_before = u.posz();
12565  u.move_to( tripoint_abs_ms( u.get_location().xy(), z_after ) );
12566 
12567  // Shift the map itself
12568  m.vertical_shift( z_after );
12569 
12570  vertical_notes( z_before, z_after );
12571 
12572  return z_before != z_after;
12573 }
void vertical_notes(int z_before, int z_after)
Add goes up/down auto_notes (if turned on)
Definition: game.cpp:12575

References debugmsg, Creature::get_location(), m, Creature::move_to(), OVERMAP_DEPTH, OVERMAP_HEIGHT, Creature::posz(), scent_map::reset(), scent, u, vertical_notes(), map::vertical_shift(), and coords::coord_point< Point, Origin, Scale, InBounds >::xy().

Referenced by place_player(), and vertical_move().

◆ void_async_anim_curses()

void game::void_async_anim_curses ( )

Definition at line 3933 of file game.cpp.

3934 {
3935  async_anim_layer_curses.clear();
3936 }

References async_anim_layer_curses.

◆ void_blink_curses()

void game::void_blink_curses ( )

Definition at line 3959 of file game.cpp.

3960 {
3961  blink_layer_curses.clear();
3962 }

References blink_layer_curses.

Referenced by draw().

◆ walk_move()

bool game::walk_move ( const tripoint dest,
bool  via_ramp = false,
bool  furniture_move = false 
)

TODO: This should really use the mounted creatures stamina, if mounted. Monsters don't currently have stamina however. For the time being just don't burn players stamina when mounted.

Dexterity decreases chance of tentacles getting stuck to the ground Intelligence decreases chance of tentacles getting stuck to the ground

Definition at line 10533 of file game.cpp.

10534 {
10536  if( u.get_size() > creature_size::medium ) {
10537  add_msg( m_warning, _( "You can't fit there." ) );
10538  return false; // character too large to fit through a tight passage
10539  }
10540  if( u.is_mounted() ) {
10541  monster *mount = u.mounted_creature.get();
10542  if( mount->get_size() > creature_size::medium ) {
10543  add_msg( m_warning, _( "Your mount can't fit there." ) );
10544  return false; // char's mount is too large for tight passages
10545  }
10546  }
10547  }
10548 
10549  const int ramp_adjust = via_ramp ? u.posz() : dest_loc.z;
10550  const float dest_light_level = get_map().ambient_light_at( tripoint( dest_loc.xy(), ramp_adjust ) );
10551 
10552  // Allow players with nyctophobia to move freely through cloudy and dark tiles
10553  const float nyctophobia_threshold = LIGHT_AMBIENT_LIT - 3.0f;
10554 
10555  // Forbid players from moving through very dark tiles, unless they are running or took xanax
10557  dest_light_level < nyctophobia_threshold ) {
10558  add_msg( m_bad,
10559  _( "It's so dark and scary in there! You can't force yourself to walk into this tile. Switch to running movement mode to move there." ) );
10560  return false;
10561  }
10562 
10563  if( u.is_mounted() ) {
10564  monster *mons = u.mounted_creature.get();
10565  if( mons->has_flag( mon_flag_RIDEABLE_MECH ) ) {
10566  if( !mons->check_mech_powered() ) {
10567  add_msg( m_bad, _( "Your %s refuses to move as its batteries have been drained." ),
10568  mons->get_name() );
10569  return false;
10570  }
10571  }
10572  if( !mons->move_effects( false ) ) {
10573  add_msg( m_bad, _( "You cannot move as your %s isn't able to move." ), mons->get_name() );
10574  return false;
10575  }
10576  }
10577  const optional_vpart_position vp_here = m.veh_at( u.pos() );
10578  const optional_vpart_position vp_there = m.veh_at( dest_loc );
10579 
10580  bool pushing = false; // moving -into- grabbed tile; skip check for move_cost > 0
10581  bool pulling = false; // moving -away- from grabbed tile; check for move_cost > 0
10582  bool shifting_furniture = false; // moving furniture and staying still; skip check for move_cost > 0
10583 
10584  const tripoint furn_pos = u.pos() + u.grab_point;
10585  const tripoint furn_dest = dest_loc + tripoint( u.grab_point.xy(), 0 );
10586 
10587  bool grabbed = u.get_grab_type() != object_type::NONE;
10588  if( grabbed ) {
10589  const tripoint dp = dest_loc - u.pos();
10590  pushing = dp.xy() == u.grab_point.xy();
10591  pulling = dp.xy() == -u.grab_point.xy();
10592  }
10593 
10594  // Now make sure we're actually holding something
10595  const vehicle *grabbed_vehicle = nullptr;
10596  const optional_vpart_position vp_grabbed = m.veh_at( u.pos() + u.grab_point );
10597  if( grabbed && u.get_grab_type() == object_type::FURNITURE ) {
10598  // We only care about shifting, because it's the only one that can change our destination
10599  if( m.has_furn( u.pos() + u.grab_point ) ) {
10600  shifting_furniture = !pushing && !pulling;
10601  } else {
10602  // We were grabbing a furniture that isn't there
10603  grabbed = false;
10604  }
10605  } else if( grabbed && u.get_grab_type() == object_type::VEHICLE ) {
10606  grabbed_vehicle = veh_pointer_or_null( m.veh_at( u.pos() + u.grab_point ) );
10607  if( grabbed_vehicle == nullptr ) {
10608  // We were grabbing a vehicle that isn't there anymore
10609  grabbed = false;
10610  }
10611  } else if( grabbed ) {
10612  // We were grabbing something WEIRD, let's pretend we weren't
10613  grabbed = false;
10614  }
10615  if( u.grab_point != tripoint_zero && !grabbed && !furniture_move ) {
10616  add_msg( m_warning, _( "Can't find grabbed object." ) );
10618  }
10619 
10620  if( m.impassable( dest_loc ) && !pushing && !shifting_furniture ) {
10621  if( vp_there && u.mounted_creature && u.mounted_creature->has_flag( mon_flag_RIDEABLE_MECH ) &&
10622  vp_there->vehicle().handle_potential_theft( u ) ) {
10623  tripoint diff = dest_loc - u.pos();
10624  if( diff.x < 0 ) {
10625  diff.x -= 2;
10626  } else if( diff.x > 0 ) {
10627  diff.x += 2;
10628  }
10629  if( diff.y < 0 ) {
10630  diff.y -= 2;
10631  } else if( diff.y > 0 ) {
10632  diff.y += 2;
10633  }
10634  u.mounted_creature->shove_vehicle( dest_loc + diff.xy(),
10635  dest_loc );
10636  }
10637  return false;
10638  }
10639  if( vp_there && !vp_there->vehicle().handle_potential_theft( u ) ) {
10640  return false;
10641  }
10642  if( u.is_mounted() && !pushing && vp_there ) {
10643  add_msg( m_warning, _( "You cannot board a vehicle whilst riding." ) );
10644  return false;
10645  }
10646  u.set_underwater( false );
10647 
10648  if( vp_there && !u.move_in_vehicle( static_cast<Creature *>( &u ), dest_loc ) ) {
10649  return false;
10650  }
10651 
10652  if( !shifting_furniture && !pushing && is_dangerous_tile( dest_loc ) ) {
10653  std::vector<std::string> harmful_stuff = get_dangerous_tile( dest_loc );
10654  if( harmful_stuff.size() == 1 && harmful_stuff[0] == "ledge" ) {
10655  iexamine::ledge( u, dest_loc );
10656  return true;
10657  } else if( get_option<std::string>( "DANGEROUS_TERRAIN_WARNING_PROMPT" ) == "ALWAYS" &&
10658  !prompt_dangerous_tile( dest_loc ) ) {
10659  return true;
10660  } else if( get_option<std::string>( "DANGEROUS_TERRAIN_WARNING_PROMPT" ) == "RUNNING" &&
10661  ( !u.is_running() || !prompt_dangerous_tile( dest_loc ) ) ) {
10662  add_msg( m_warning,
10663  _( "Stepping into that %1$s looks risky. Run into it if you wish to enter anyway." ),
10664  enumerate_as_string( harmful_stuff ) );
10665  return true;
10666  } else if( get_option<std::string>( "DANGEROUS_TERRAIN_WARNING_PROMPT" ) == "CROUCHING" &&
10667  ( !u.is_crouching() || !prompt_dangerous_tile( dest_loc ) ) ) {
10668  add_msg( m_warning,
10669  _( "Stepping into that %1$s looks risky. Crouch and move into it if you wish to enter anyway." ),
10670  enumerate_as_string( harmful_stuff ) );
10671  return true;
10672  } else if( get_option<std::string>( "DANGEROUS_TERRAIN_WARNING_PROMPT" ) == "NEVER" &&
10673  !u.is_running() ) {
10674  add_msg( m_warning,
10675  _( "Stepping into that %1$s looks risky. Run into it if you wish to enter anyway." ),
10676  enumerate_as_string( harmful_stuff ) );
10677  return true;
10678  }
10679  }
10680  // Used to decide whether to print a 'moving is slow message
10681  const int mcost_from = m.move_cost( u.pos() ); //calculate this _before_ calling grabbed_move
10682 
10683  int modifier = 0;
10684  if( grabbed && u.get_grab_type() == object_type::FURNITURE && u.pos() + u.grab_point == dest_loc ) {
10685  modifier = -m.furn( dest_loc ).obj().movecost;
10686  }
10687 
10688  const int mcost = m.combined_movecost( u.pos(), dest_loc, grabbed_vehicle, modifier,
10689  via_ramp );
10690 
10691  if( !furniture_move && grabbed_move( dest_loc - u.pos(), via_ramp ) ) {
10692  return true;
10693  } else if( mcost == 0 ) {
10694  return false;
10695  }
10696  bool diag = trigdist && u.posx() != dest_loc.x && u.posy() != dest_loc.y;
10697  const int previous_moves = u.get_moves();
10698  if( u.is_mounted() ) {
10699  auto *crit = u.mounted_creature.get();
10700  if( !crit->has_flag( mon_flag_RIDEABLE_MECH ) &&
10706  add_msg( m_warning, _( "You cannot pass obstacles whilst mounted." ) );
10707  return false;
10708  }
10709  const double base_moves = u.run_cost( mcost, diag ) * 100.0 / crit->get_speed();
10710  const double encumb_moves = u.get_weight() / 4800.0_gram;
10711  u.mod_moves( -static_cast<int>( std::ceil( base_moves + encumb_moves ) ) );
10712  crit->use_mech_power( u.current_movement_mode()->mech_power_use() );
10713  } else {
10714  u.mod_moves( -u.run_cost( mcost, diag ) );
10715  /**
10716  TODO:
10717  This should really use the mounted creatures stamina, if mounted.
10718  Monsters don't currently have stamina however.
10719  For the time being just don't burn players stamina when mounted.
10720  */
10721  if( grabbed_vehicle == nullptr || grabbed_vehicle->wheelcache.empty() ) {
10722  //Burn normal amount of stamina if no vehicle grabbed or vehicle lacks wheels
10723  u.burn_move_stamina( previous_moves - u.get_moves() );
10724  } else {
10725  //Burn half as much stamina if vehicle has wheels, without changing move time
10726  u.burn_move_stamina( 0.50 * ( previous_moves - u.get_moves() ) );
10727  }
10728  }
10729  // Max out recoil & reset aim point
10730  u.recoil = MAX_RECOIL;
10731  u.last_target_pos = std::nullopt;
10732 
10733  // Print a message if movement is slow
10734  const int mcost_to = m.move_cost( dest_loc ); //calculate this _after_ calling grabbed_move
10737  dest_loc ); //fungal furniture has no slowing effect on Mycus characters
10738  const bool slowed = ( ( !u.has_proficiency( proficiency_prof_parkour ) && ( mcost_to > 2 ||
10739  mcost_from > 2 ) ) ||
10740  mcost_to > 4 || mcost_from > 4 ) ||
10741  ( !u.has_trait( trait_M_IMMUNE ) && fungus );
10742  if( slowed && !u.is_mounted() ) {
10743  // Unless u.pos() has a higher movecost than dest_loc, state that dest_loc is the cause
10744  if( mcost_to >= mcost_from ) {
10745  if( auto displayed_part = vp_there.part_displayed() ) {
10746  add_msg( m_warning, _( "Moving onto this %s is slow!" ),
10747  displayed_part->part().name() );
10748  sfx::do_obstacle( displayed_part->part().info().id.str() );
10749  } else {
10750  add_msg( m_warning, _( "Moving onto this %s is slow!" ), m.name( dest_loc ) );
10751  if( m.has_furn( dest_loc ) ) {
10752  sfx::do_obstacle( m.furn( dest_loc ).id().str() );
10753  } else {
10754  sfx::do_obstacle( m.ter( dest_loc ).id().str() );
10755  }
10756  }
10757  } else {
10758  if( auto displayed_part = vp_here.part_displayed() ) {
10759  add_msg( m_warning, _( "Moving off of this %s is slow!" ),
10760  displayed_part->part().name() );
10761  sfx::do_obstacle( displayed_part->part().info().id.str() );
10762  } else {
10763  add_msg( m_warning, _( "Moving off of this %s is slow!" ), m.name( u.pos() ) );
10764  if( m.has_furn( u.pos() ) ) {
10765  sfx::do_obstacle( m.furn( u.pos() ).id().str() );
10766  } else {
10767  sfx::do_obstacle( m.ter( u.pos() ).id().str() );
10768  }
10769  }
10770  }
10771  }
10772  if( !u.is_mounted() && u.has_trait( trait_LEG_TENT_BRACE ) &&
10773  u.is_barefoot() ) {
10774  // DX and IN are long suits for Cephalopods,
10775  // so this shouldn't cause too much hardship
10776  // Presumed that if it's swimmable, they're
10777  // swimming and won't stick
10778  ///\EFFECT_DEX decreases chance of tentacles getting stuck to the ground
10779 
10780  ///\EFFECT_INT decreases chance of tentacles getting stuck to the ground
10781  if( !m.has_flag( ter_furn_flag::TFLAG_SWIMMABLE, dest_loc ) &&
10782  one_in( 80 + u.dex_cur + u.int_cur ) ) {
10783  add_msg( _( "Your tentacles stick to the ground, but you pull them free." ) );
10784  u.mod_sleepiness( 1 );
10785  }
10786  }
10787 
10789 
10790  //only clatter items every so often based on activity level
10791  if( to_turns<int>( calendar::turn - u.last_pocket_noise ) > std::max( static_cast<int>
10792  ( 10 - u.activity_level() ), 1 ) ) {
10795  }
10796 
10798  add_msg( m_good, _( "You are hiding in the %s." ), m.name( dest_loc ) );
10799  }
10800 
10801  tripoint oldpos = u.pos();
10802  tripoint old_abs_pos = m.getabs( oldpos );
10803 
10804  bool moving = dest_loc != oldpos;
10805 
10806  point submap_shift = place_player( dest_loc );
10807  point ms_shift = sm_to_ms_copy( submap_shift );
10808  oldpos = oldpos - ms_shift;
10809 
10810  if( moving ) {
10811  cata_event_dispatch::avatar_moves( old_abs_pos, u, m );
10812 
10813  // Add trail animation when sprinting
10814  if( get_option<bool>( "ANIMATIONS" ) && u.is_running() ) {
10815  if( u.posy() < oldpos.y ) {
10816  if( u.posx() < oldpos.x ) {
10817  draw_async_anim( oldpos, "run_nw", "\\", c_light_gray );
10818  } else if( u.posx() == oldpos.x ) {
10819  draw_async_anim( oldpos, "run_n", "|", c_light_gray );
10820  } else {
10821  draw_async_anim( oldpos, "run_ne", "/", c_light_gray );
10822  }
10823  } else if( u.posy() == oldpos.y ) {
10824  if( u.posx() < oldpos.x ) {
10825  draw_async_anim( oldpos, "run_w", "-", c_light_gray );
10826  } else {
10827  draw_async_anim( oldpos, "run_e", "-", c_light_gray );
10828  }
10829  } else {
10830  if( u.posx() < oldpos.x ) {
10831  draw_async_anim( oldpos, "run_sw", "/", c_light_gray );
10832  } else if( u.posx() == oldpos.x ) {
10833  draw_async_anim( oldpos, "run_s", "|", c_light_gray );
10834  } else {
10835  draw_async_anim( oldpos, "run_se", "\\", c_light_gray );
10836  }
10837  }
10838  }
10839  }
10840 
10841  if( furniture_move ) {
10842  // Adjust the grab_point if player has changed z level.
10843  u.grab_point.z -= u.posz() - oldpos.z;
10844  }
10845 
10846  if( grabbed_vehicle ) {
10847  // Vehicle might be at different z level than the grabbed part.
10848  u.grab_point.z = vp_grabbed->pos().z - u.posz();
10849  }
10850 
10851  if( pulling ) {
10852  const tripoint shifted_furn_pos = furn_pos - ms_shift;
10853  const tripoint shifted_furn_dest = furn_dest - ms_shift;
10854  const time_duration fire_age = m.get_field_age( shifted_furn_pos, fd_fire );
10855  const int fire_intensity = m.get_field_intensity( shifted_furn_pos, fd_fire );
10856  m.remove_field( shifted_furn_pos, fd_fire );
10857  m.set_field_intensity( shifted_furn_dest, fd_fire, fire_intensity );
10858  m.set_field_age( shifted_furn_dest, fd_fire, fire_age );
10859  }
10860 
10861  if( u.is_hauling() ) {
10862  start_hauling( oldpos );
10863  }
10864 
10865  on_move_effects();
10866 
10867  return true;
10868 }
void burn_move_stamina(int moves)
Definition: character.cpp:6975
units::mass get_weight() const override
Returns body weight plus weight of inventory and worn/wielded items.
Definition: character.cpp:3889
float activity_level() const
Definition: character.cpp:4978
void make_footstep_noise() const
Definition: character.cpp:2235
bool move_in_vehicle(Creature *c, const tripoint &dest_loc) const
Attempt to enter a tile in a vehicle.
Definition: character.cpp:8021
creature_size get_size() const override
Get size class of character.
Definition: character.cpp:824
std::optional< tripoint > last_target_pos
Definition: character.h:2762
int run_cost(int base_cost, bool diag=false) const
Returns the player's modified base movement cost.
int int_cur
Definition: character.h:579
void make_clatter_sound() const
Definition: character.cpp:2256
void mod_sleepiness(int nsleepiness)
Definition: character.cpp:4544
time_point last_pocket_noise
Definition: avatar.h:375
bool grabbed_move(const tripoint &dp, bool via_ramp)
Check for dangerous stuff at dest_loc, return false if the player decides not to step there.
Definition: game.cpp:11632
void draw_async_anim(const tripoint &p, const std::string &tile_id, const std::string &ncstr="", const nc_color &nccol=c_black)
Definition: animation.cpp:893
const string_id< T > & id() const
Definition: ammo_effect.cpp:33
int combined_movecost(const tripoint &from, const tripoint &to, const vehicle *ignored_vehicle=nullptr, int modifier=0, bool flying=false, bool via_ramp=false) const
Cost to move out of one tile and into the next.
Definition: map.cpp:2519
bool move_effects(bool attacking) override
Processes effects which may prevent the monster from moving (bear traps, crushed, etc....
Definition: monster.cpp:2205
creature_size get_size() const override
Definition: monster.cpp:3503
std::optional< vpart_reference > part_displayed() const
Definition: vehicle.cpp:2732
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const json_character_flag json_flag_NYCTOPHOBIA("NYCTOPHOBIA")
static const efftype_id effect_took_xanax("took_xanax")
@ TFLAG_BARRICADABLE_DOOR_REINFORCED
@ TFLAG_BARRICADABLE_DOOR_DAMAGED
double ceil(std::vector< double > const &params)
void fungus(Character &you, const tripoint &examp)
Remove furniture.
Definition: iexamine.cpp:2464
void ledge(Character &you, const tripoint &examp)
Definition: iexamine.cpp:5378
void do_obstacle(const std::string &obst="")
Definition: sounds.cpp:2035

References _, Character::activity_level(), add_msg(), map::ambient_light_at(), cata_event_dispatch::avatar_moves(), Character::burn_move_stamina(), c_light_gray, ceil(), monster::check_mech_powered(), map::combined_movecost(), Character::current_movement_mode(), Character::dex_cur, sfx::do_obstacle(), draw_async_anim(), effect_took_xanax, enumerate_as_string(), fd_fire, iexamine::fungus(), map::furn(), FURNITURE, get_dangerous_tile(), map::get_field_age(), map::get_field_intensity(), avatar::get_grab_type(), get_map, Creature::get_moves(), monster::get_name(), Character::get_size(), monster::get_size(), Character::get_weight(), map::getabs(), avatar::grab(), Character::grab_point, grabbed_move(), Creature::has_effect(), Character::has_flag(), monster::has_flag(), map::has_flag(), map::has_flag_ter(), map::has_flag_ter_or_furn(), map::has_furn(), Character::has_proficiency(), Character::has_trait(), int_id< T >::id(), map::impassable(), Character::int_cur, Character::is_barefoot(), Character::is_crouching(), is_dangerous_tile(), Character::is_hauling(), Character::is_mounted(), Character::is_running(), json_flag_NYCTOPHOBIA, avatar::last_pocket_noise, Character::last_target_pos, iexamine::ledge(), LIGHT_AMBIENT_LIT, m, m_bad, m_good, m_warning, Character::make_clatter_sound(), Character::make_footstep_noise(), max(), MAX_RECOIL, move_mode::mech_power_use(), medium, Creature::mod_moves(), Character::mod_sleepiness(), mon_flag_RIDEABLE_MECH, Character::mounted_creature, map::move_cost(), monster::move_effects(), Character::move_in_vehicle(), map_data_common_t::movecost, map::name(), NONE, int_id< T >::obj(), on_move_effects(), one_in(), optional_vpart_position::part_displayed(), place_player(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), proficiency_prof_parkour, prompt_dangerous_tile(), Character::recoil, map::remove_field(), Character::run_cost(), map::set_field_age(), map::set_field_intensity(), Character::set_underwater(), sm_to_ms_copy(), start_hauling(), string_id< T >::str(), map::ter(), TFLAG_BARRICADABLE_DOOR, TFLAG_BARRICADABLE_DOOR_DAMAGED, TFLAG_BARRICADABLE_DOOR_REINFORCED, TFLAG_FUNGUS, TFLAG_HIDE_PLACE, TFLAG_MOUNTABLE, TFLAG_OPENCLOSE_INSIDE, TFLAG_SMALL_PASSAGE, TFLAG_SWIMMABLE, trait_LEG_TENT_BRACE, trait_M_IMMUNE, trigdist, tripoint, tripoint_zero, calendar::turn, u, map::veh_at(), veh_pointer_or_null(), VEHICLE, vehicle::wheelcache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by swap_critters().

◆ water_affect_items()

void game::water_affect_items ( Character ch) const

Destroy / dissolve character items when in water.

Definition at line 11703 of file game.cpp.

11704 {
11705  for( item_location &loc : ch.all_items_loc() ) {
11706  // check flag first because its cheaper
11707  if( loc->has_flag( flag_WATER_DISSOLVE ) && !loc.protected_from_liquids() ) {
11708  add_msg_if_player_sees( ch.pos(), m_bad, _( "%1$s %2$s dissolved in the water!" ),
11709  ch.disp_name( true, true ), loc->display_name() );
11710  loc.remove_item();
11711  } else if( loc->has_flag( flag_WATER_BREAK ) && !loc->is_broken()
11712  && !loc.protected_from_liquids() ) {
11713 
11714  add_msg_if_player_sees( ch.pos(), m_bad, _( "The water destroyed %1$s %2$s!" ),
11715  ch.disp_name( true ), loc->display_name() );
11716  loc->deactivate();
11717  // TODO: Maybe different types of wet faults? But I can't think of any.
11718  // This just means it's still too wet to use.
11719  loc->set_fault( random_entry( fault::get_by_type( std::string( "wet" ) ) ) );
11720  // An electronic item in water is also shorted.
11721  if( loc->has_flag( flag_ELECTRONIC ) ) {
11722  loc->set_fault( random_entry( fault::get_by_type( std::string( "shorted" ) ) ) );
11723  }
11724  } else if( loc->has_flag( flag_WATER_BREAK_ACTIVE ) && !loc->is_broken()
11725  && !loc.protected_from_liquids() ) {
11726  const int wetness_add = 5100 * std::log10( units::to_milliliter( loc->volume() ) );
11727  loc->wetness += wetness_add;
11728  loc->wetness = std::min( loc->wetness, 5 * wetness_add );
11729  } else if( loc->typeId() == itype_towel && !loc.protected_from_liquids() ) {
11730  loc->convert( itype_towel_wet, &ch ).active = true;
11731  }
11732  }
11733 }
std::vector< item_location > all_items_loc()
static const std::list< fault_id > & get_by_type(const std::string &type)
Definition: fault.cpp:147
const flag_id flag_WATER_BREAK("WATER_BREAK")
const flag_id flag_WATER_DISSOLVE("WATER_DISSOLVE")
const flag_id flag_WATER_BREAK_ACTIVE("WATER_BREAK_ACTIVE")
const flag_id flag_ELECTRONIC("ELECTRONIC")
static const itype_id itype_towel_wet("towel_wet")
static const itype_id itype_towel("towel")
void add_msg_if_player_sees(const tripoint &target, std::string msg)
Definition: messages.cpp:1007
constexpr value_type to_milliliter(const quantity< value_type, volume_in_milliliter_tag > &v)
Definition: units.h:316

References _, add_msg_if_player_sees(), Character::all_items_loc(), Character::disp_name(), flag_ELECTRONIC, flag_WATER_BREAK, flag_WATER_BREAK_ACTIVE, flag_WATER_DISSOLVE, fault::get_by_type(), itype_towel, itype_towel_wet, m_bad, min(), Creature::pos(), random_entry(), and units::to_milliliter().

Referenced by fling_creature().

◆ wield() [1/2]

void game::wield ( )
private

Definition at line 10212 of file game.cpp.

10213 {
10215 
10216  if( loc ) {
10217  wield( loc );
10218  } else {
10219  add_msg( _( "Never mind." ) );
10220  }
10221 }
item_location wield(avatar &you)
Item wielding/unwielding menu.

References _, add_msg(), u, and game_menus::inv::wield().

Referenced by do_regular_action(), inventory_item_menu(), and wield().

◆ wield() [2/2]

void game::wield ( item_location  loc)
private

Definition at line 10110 of file game.cpp.

10111 {
10112  if( !loc ) {
10113  debugmsg( "ERROR: tried to wield null item" );
10114  return;
10115  }
10116  const item_location weapon = u.get_wielded_item();
10117  if( weapon && weapon != loc && weapon->has_item( *loc ) ) {
10118  add_msg( m_info, _( "You need to put the bag away before trying to wield something from it." ) );
10119  return;
10120  }
10121  if( u.has_wield_conflicts( *loc ) ) {
10122  const bool is_unwielding = u.is_wielding( *loc );
10123  const auto ret = u.can_unwield( *loc );
10124 
10125  if( !ret.success() ) {
10126  add_msg( m_info, "%s", ret.c_str() );
10127  }
10128 
10129  if( !u.unwield() ) {
10130  return;
10131  }
10132 
10133  if( is_unwielding ) {
10134  if( !u.martial_arts_data->selected_is_none() ) {
10135  u.martial_arts_data->martialart_use_message( u );
10136  }
10137  return;
10138  }
10139  }
10140  const auto ret = u.can_wield( *loc );
10141  if( !ret.success() ) {
10142  add_msg( m_info, "%s", ret.c_str() );
10143  }
10144  // Need to do this here because holster_actor::use() checks if/where the item is worn
10145  item &target = *loc.get_item();
10146  if( target.get_use( "holster" ) && !target.empty() ) {
10147  //~ %1$s: holster name
10148  if( query_yn( pgettext( "holster", "Draw from %1$s?" ),
10149  target.tname() ) ) {
10150  u.invoke_item( &target );
10151  return;
10152  }
10153  }
10154 
10155  // Can't use loc.obtain() here because that would cause things to spill.
10156  item to_wield = *loc.get_item();
10157  item_location::type location_type = loc.where();
10158  tripoint pos = loc.position();
10159  const int obtain_cost = loc.obtain_cost( u );
10160  int worn_index = INT_MIN;
10161 
10162  // Need to account for case where we're trying to wield a weapon that belongs to someone else
10163  if( !avatar_action::check_stealing( u, *loc.get_item() ) ) {
10164  return;
10165  }
10166 
10167  if( u.is_worn( *loc.get_item() ) ) {
10168  auto ret = u.can_takeoff( *loc.get_item() );
10169  if( !ret.success() ) {
10170  add_msg( m_info, "%s", ret.c_str() );
10171  return;
10172  }
10173  int item_pos = u.get_item_position( loc.get_item() );
10174  if( item_pos != INT_MIN ) {
10175  worn_index = Character::worn_position_to_index( item_pos );
10176  }
10177  }
10178  loc.remove_item();
10179  if( !u.wield( to_wield, obtain_cost ) ) {
10180  switch( location_type ) {
10182  // this will not cause things to spill, as it is inside another item
10183  loc = loc.obtain( u );
10184  wield( loc );
10185  break;
10187  if( worn_index != INT_MIN ) {
10188  u.worn.insert_item_at_index( to_wield, worn_index );
10189  } else {
10190  u.i_add( to_wield, true, nullptr, loc.get_item() );
10191  }
10192  break;
10194  m.add_item( pos, to_wield );
10195  break;
10197  const std::optional<vpart_reference> ovp = m.veh_at( pos ).cargo();
10198  // If we fail to return the item to the vehicle for some reason, add it to the map instead.
10199  if( !ovp || !ovp->vehicle().add_item( ovp->part(), to_wield ) ) {
10200  m.add_item( pos, to_wield );
10201  }
10202  break;
10203  }
10205  debugmsg( "Failed wield from invalid item location" );
10206  break;
10207  }
10208  return;
10209  }
10210 }
ret_val< void > can_takeoff(const item &it, const std::list< item > *res=nullptr)
Check player capable of taking off an item.
ret_val< void > can_unwield(const item &it) const
Check player capable of unwielding an item.
Definition: character.cpp:3301
bool has_wield_conflicts(const item &it) const
Returns true if the character is wielding something and it can't be combined with the item passed as ...
Definition: character.cpp:7894
bool is_worn(const item &thing) const
Definition: character.h:1911
static int worn_position_to_index(int position)
Definition: character.h:1906
bool is_wielding(const item &target) const
Definition: character.cpp:3319
item_location i_add(item it, bool should_stack=true, const item *avoid=nullptr, const item *original_inventory_item=nullptr, bool allow_drop=true, bool allow_wield=true, bool ignore_pkt_settings=false)
Adds the item to the character's worn items or wields it, or prompts if the Character cannot pick it ...
bool wield(item_location target)
Definition: avatar.cpp:1385
type where() const
Returns the type of location where the item is found.
void remove_item()
Removes the selected item from the game.
tripoint position() const
Returns the position where the item is found.
int obtain_cost(const Character &ch, int qty=-1) const
Calculate (but do not deduct) number of moves required to obtain an item.
bool empty() const
Definition: item.cpp:15135
item & add_item(const tripoint &p, item new_item, int copies)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:5329
std::optional< vpart_reference > cargo() const
Definition: vehicle.cpp:2710
void insert_item_at_index(const item &clothing, int index)
bool check_stealing(Character &who, item &weapon)
Check if avatar is stealing a weapon.

References _, map::add_item(), add_msg(), Character::can_takeoff(), Character::can_unwield(), Character::can_wield(), optional_vpart_position::cargo(), item_location::character, avatar_action::check_stealing(), item_location::container, debugmsg, item::empty(), item_location::get_item(), Character::get_item_position(), item::get_use(), Character::get_wielded_item(), visitable::has_item(), Character::has_wield_conflicts(), Character::i_add(), outfit::insert_item_at_index(), item_location::invalid, avatar::invoke_item(), Character::is_wielding(), Character::is_worn(), m, m_info, item_location::map, Character::martial_arts_data, item_location::obtain(), item_location::obtain_cost(), pgettext, math_opers::pos(), item_location::position(), query_yn(), item_location::remove_item(), cata::hash64_detail::ret, item::tname(), u, Character::unwield(), map::veh_at(), item_location::vehicle, item_location::where(), wield(), avatar::wield(), Character::worn, and Character::worn_position_to_index().

◆ write_memorial_file()

void game::write_memorial_file ( std::string  sLastWords)

Writes information about the character out to a text file timestamped with the time of the file was made.

This serves as a record of the character's state at the time the memorial was made (usually upon death) and accomplishments in a human-readable format.

Definition at line 3532 of file game.cpp.

3533 {
3534  const std::string &memorial_dir = PATH_INFO::memorialdir();
3535  const std::string &memorial_active_world_dir = memorial_dir +
3536  world_generator->active_world->world_name + "/";
3537 
3538  //Check if both dirs exist. Nested assure_dir_exist fails if the first dir of the nested dir does not exist.
3539  if( !assure_dir_exist( memorial_dir ) ) {
3540  dbg( D_ERROR ) << "game:write_memorial_file: Unable to make memorial directory.";
3541  debugmsg( "Could not make '%s' directory", memorial_dir );
3542  return;
3543  }
3544 
3545  if( !assure_dir_exist( memorial_active_world_dir ) ) {
3546  dbg( D_ERROR ) <<
3547  "game:write_memorial_file: Unable to make active world directory in memorial directory.";
3548  debugmsg( "Could not make '%s' directory", memorial_active_world_dir );
3549  return;
3550  }
3551 
3552  // <name>-YYYY-MM-DD-HH-MM-SS.txt
3553  // 123456789012345678901234 ~> 24 chars + a null
3554  constexpr size_t suffix_len = 24 + 1;
3555  constexpr size_t max_name_len = FILENAME_MAX - suffix_len;
3556 
3557  const size_t name_len = u.name.size();
3558  // Here -1 leaves space for the ~
3559  const size_t truncated_name_len = ( name_len >= max_name_len ) ? ( max_name_len - 1 ) : name_len;
3560 
3561  std::ostringstream memorial_file_path;
3562  memorial_file_path << memorial_active_world_dir;
3563 
3564  if( get_options().has_option( "ENCODING_CONV" ) && !get_option<bool>( "ENCODING_CONV" ) ) {
3565  // Use the default locale to replace non-printable characters with _ in the player name.
3566  std::locale locale {"C"};
3567  std::replace_copy_if( std::begin( u.name ), std::begin( u.name ) + truncated_name_len,
3568  std::ostream_iterator<char>( memorial_file_path ),
3569  [&]( const char c ) {
3570  return !std::isgraph( c, locale );
3571  }, '_' );
3572  } else {
3573  memorial_file_path << u.name;
3574  }
3575 
3576  // Add a ~ if the player name was actually truncated.
3577  memorial_file_path << ( ( truncated_name_len != name_len ) ? "~-" : "-" );
3578 
3579  // Add a timestamp for uniqueness.
3580 
3581 #if defined(_WIN32)
3582  SYSTEMTIME current_time;
3583  GetLocalTime( &current_time );
3584  memorial_file_path << string_format( "%d-%02d-%02d-%02d-%02d-%02d",
3585  current_time.wYear, current_time.wMonth, current_time.wDay,
3586  current_time.wHour, current_time.wMinute, current_time.wSecond );
3587 #else
3588  // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3589  char buffer[suffix_len] {};
3590  std::time_t t = std::time( nullptr );
3591  tm current_time;
3592  localtime_r( &t, &current_time );
3593  size_t result = std::strftime( buffer, suffix_len, "%Y-%m-%d-%H-%M-%S", &current_time );
3594  if( result == 0 ) {
3595  cata_fatal( "Could not construct filename" );
3596  }
3597  memorial_file_path << buffer;
3598 #endif
3599 
3600  const std::string text_path_string = memorial_file_path.str() + ".txt";
3601  const std::string json_path_string = memorial_file_path.str() + ".json";
3602 
3603  write_to_file( text_path_string, [&]( std::ostream & fout ) {
3604  memorial().write_text_memorial( fout, sLastWords );
3605  }, _( "player memorial" ) );
3606 
3607  write_to_file( json_path_string, [&]( std::ostream & fout ) {
3608  memorial().write_json_memorial( fout );
3609  }, _( "player memorial" ) );
3610 }
void write_json_memorial(std::ostream &memorial_file) const
void write_text_memorial(std::ostream &memorial_file, const std::string &epitaph) const
std::string memorialdir()
Definition: path_info.cpp:330

References _, assure_dir_exist(), c, cata_fatal, D_ERROR, dbg, debugmsg, get_options(), options_manager::has_option(), memorial(), PATH_INFO::memorialdir(), Character::name, string_format(), u, world_generator, memorial_logger::write_json_memorial(), memorial_logger::write_text_memorial(), and write_to_file().

◆ zones_manager()

void game::zones_manager ( )

Definition at line 6942 of file game.cpp.

6943 {
6944  const tripoint stored_view_offset = u.view_offset;
6945 
6947 
6948  const int zone_ui_height = 14;
6949  const int zone_options_height = debug_mode ? 6 : 7;
6950 
6951  const int width = 45;
6952 
6953  int offsetX = 0;
6954  int max_rows = 0;
6955 
6956  catacurses::window w_zones;
6957  catacurses::window w_zones_border;
6958  catacurses::window w_zones_info;
6959  catacurses::window w_zones_info_border;
6960  catacurses::window w_zones_options;
6961 
6962  bool show = true;
6963 
6964  ui_adaptor ui;
6965  ui.on_screen_resize( [&]( ui_adaptor & ui ) {
6966  if( !show ) {
6967  ui.position( point_zero, point_zero );
6968  return;
6969  }
6970  offsetX = get_option<std::string>( "SIDEBAR_POSITION" ) != "left" ?
6971  TERMX - width : 0;
6972  const int w_zone_height = TERMY - zone_ui_height;
6973  max_rows = w_zone_height - 2;
6974  w_zones = catacurses::newwin( w_zone_height - 2, width - 2,
6975  point( offsetX + 1, 1 ) );
6976  w_zones_border = catacurses::newwin( w_zone_height, width,
6977  point( offsetX, 0 ) );
6978  w_zones_info = catacurses::newwin( zone_ui_height - zone_options_height - 1,
6979  width - 2, point( offsetX + 1, w_zone_height ) );
6980  w_zones_info_border = catacurses::newwin( zone_ui_height, width,
6981  point( offsetX, w_zone_height ) );
6982  w_zones_options = catacurses::newwin( zone_options_height - 1, width - 2,
6983  point( offsetX + 1, TERMY - zone_options_height ) );
6984 
6985  ui.position( point( offsetX, 0 ), point( width, TERMY ) );
6986  } );
6987  ui.mark_resize();
6988 
6989  input_context ctxt( "ZONES_MANAGER" );
6990  ctxt.register_navigate_ui_list();
6991  ctxt.register_action( "CONFIRM" );
6992  ctxt.register_action( "QUIT" );
6993  ctxt.register_action( "ADD_ZONE" );
6994  ctxt.register_action( "ADD_PERSONAL_ZONE" );
6995  ctxt.register_action( "REMOVE_ZONE" );
6996  ctxt.register_action( "MOVE_ZONE_UP" );
6997  ctxt.register_action( "MOVE_ZONE_DOWN" );
6998  ctxt.register_action( "SHOW_ZONE_ON_MAP" );
6999  ctxt.register_action( "ENABLE_ZONE" );
7000  ctxt.register_action( "DISABLE_ZONE" );
7001  ctxt.register_action( "TOGGLE_ZONE_DISPLAY" );
7002  ctxt.register_action( "ENABLE_PERSONAL_ZONES" );
7003  ctxt.register_action( "DISABLE_PERSONAL_ZONES" );
7004  ctxt.register_action( "SHOW_ALL_ZONES" );
7005  ctxt.register_action( "HELP_KEYBINDINGS" );
7006  if( debug_mode ) {
7007  ctxt.register_action( "CHANGE_FACTION" );
7008  }
7009 
7011  int start_index = 0;
7012  int active_index = 0;
7013  bool blink = false;
7014  bool stuff_changed = false;
7015  bool show_all_zones = false;
7016  int zone_cnt = 0;
7017  faction_id zones_faction( your_fac );
7018 
7019  // reset any zones that were temporarily disabled for an activity
7020  mgr.reset_disabled();
7021 
7022  // cache the players location for person zones
7023  if( mgr.has_personal_zones() ) {
7024  mgr.cache_avatar_location();
7025  }
7026 
7027  // get zones with distance between player and
7028  // zone center point <= 60 or all zones, if show_all_zones is true
7029  auto get_zones = [&]() {
7030  std::vector<zone_manager::ref_zone_data> zones;
7031  if( show_all_zones ) {
7032  zones = mgr.get_zones( zones_faction );
7033  } else {
7034  const tripoint_abs_ms u_abs_pos = u.get_location();
7035  for( zone_manager::ref_zone_data &ref : mgr.get_zones( zones_faction ) ) {
7036  const tripoint_abs_ms &zone_abs_pos = ref.get().get_center_point();
7037  if( rl_dist( u_abs_pos, zone_abs_pos ) <= ACTIVITY_SEARCH_DISTANCE ) {
7038  zones.emplace_back( ref );
7039  }
7040  }
7041  }
7042  zones.erase( std::remove_if( zones.begin(), zones.end(),
7043  []( zone_manager::ref_zone_data const & it ) {
7044  zone_type_id const type = it.get().get_type();
7045  return !debug_mode && type.is_valid() && type->hidden;
7046  } ),
7047  zones.end() );
7048  zone_cnt = static_cast<int>( zones.size() );
7049  return zones;
7050  };
7051 
7052  auto zones = get_zones();
7053 
7054  auto zones_manager_options = [&]() {
7055  werase( w_zones_options );
7056 
7057  if( zone_cnt > 0 ) {
7058  const zone_data &zone = zones[active_index].get();
7059 
7060  // NOLINTNEXTLINE(cata-use-named-point-constants)
7061  mvwprintz( w_zones_options, point( 1, 0 ), c_white, mgr.get_name_from_type( zone.get_type() ) );
7062 
7063  if( zone.has_options() ) {
7064  const auto &descriptions = zone.get_options().get_descriptions();
7065 
7066  // NOLINTNEXTLINE(cata-use-named-point-constants)
7067  mvwprintz( w_zones_options, point( 1, 1 ), c_white, _( "Options" ) );
7068 
7069  int y = 2;
7070  for( const auto &desc : descriptions ) {
7071  mvwprintz( w_zones_options, point( 3, y ), c_white, desc.first );
7072  mvwprintz( w_zones_options, point( 20, y ), c_white, desc.second );
7073  y++;
7074  }
7075  }
7076  }
7077 
7078  wnoutrefresh( w_zones_options );
7079  };
7080 
7081  std::optional<tripoint> zone_start;
7082  std::optional<tripoint> zone_end;
7083  bool zone_blink = false;
7084  bool zone_cursor = false;
7086  zone_start, zone_end, zone_blink, zone_cursor );
7087  add_draw_callback( zone_cb );
7088 
7089  // This lambda returns either absolute coordinates or relative-to-player
7090  // coordinates, depending on whether personal is false or true respectively.
7091  // In C++20 we could have the return type depend on the parameter using
7092  // if constexpr( personal ) but for now it will just return tripoints.
7093  auto query_position =
7094  [&]( bool personal = false ) -> std::optional<std::pair<tripoint, tripoint>> {
7095  on_out_of_scope invalidate_current_ui( [&]()
7096  {
7097  ui.mark_resize();
7098  } );
7099  restore_on_out_of_scope<bool> show_prev( show );
7100  restore_on_out_of_scope<std::optional<tripoint>> zone_start_prev( zone_start );
7101  restore_on_out_of_scope<std::optional<tripoint>> zone_end_prev( zone_end );
7102  show = false;
7103  zone_start = std::nullopt;
7104  zone_end = std::nullopt;
7105  ui.mark_resize();
7106 
7108  popup.on_top( true );
7109  popup.message( "%s", _( "Select first point." ) );
7110 
7111  tripoint center = u.pos() + u.view_offset;
7112 
7113  const look_around_result first =
7114  look_around( /*show_window=*/false, center, center, false, true, false );
7115  if( first.position )
7116  {
7117  popup.message( "%s", _( "Select second point." ) );
7118 
7119  const look_around_result second = look_around( /*show_window=*/false, center, *first.position,
7120  true, true, false );
7121  if( second.position ) {
7122  if( personal ) {
7123  tripoint first_rel(
7124  std::min( first.position->x - u.posx(), second.position->x - u.posx() ),
7125  std::min( first.position->y - u.posy(), second.position->y - u.posy() ),
7126  std::min( first.position->z - u.posz(), second.position->z - u.posz() ) ) ;
7127  tripoint second_rel(
7128  std::max( first.position->x - u.posx(), second.position->x - u.posx() ),
7129  std::max( first.position->y - u.posy(), second.position->y - u.posy() ),
7130  std::max( first.position->z - u.posz(), second.position->z - u.posz() ) ) ;
7131  return { { first_rel, second_rel } };
7132  }
7133  tripoint_abs_ms first_abs =
7134  m.getglobal(
7135  tripoint(
7136  std::min( first.position->x, second.position->x ),
7137  std::min( first.position->y, second.position->y ),
7138  std::min( first.position->z, second.position->z ) ) );
7139  tripoint_abs_ms second_abs =
7140  m.getglobal(
7141  tripoint(
7142  std::max( first.position->x, second.position->x ),
7143  std::max( first.position->y, second.position->y ),
7144  std::max( first.position->z, second.position->z ) ) );
7145 
7146  return { { first_abs.raw(), second_abs.raw() } };
7147  }
7148  }
7149 
7150  return std::nullopt;
7151  };
7152 
7153  ui.on_redraw( [&]( const ui_adaptor & ) {
7154  if( !show ) {
7155  return;
7156  }
7157  zones_manager_draw_borders( w_zones_border, w_zones_info_border, zone_ui_height, width );
7158  zones_manager_shortcuts( w_zones_info, zones_faction );
7159 
7160  if( zone_cnt == 0 ) {
7161  werase( w_zones );
7162  mvwprintz( w_zones, point( 2, 5 ), c_white, _( "No Zones defined." ) );
7163 
7164  } else {
7165  werase( w_zones );
7166 
7167  calcStartPos( start_index, active_index, max_rows, zone_cnt );
7168 
7169  draw_scrollbar( w_zones_border, active_index, max_rows, zone_cnt, point_south );
7170  wnoutrefresh( w_zones_border );
7171 
7172  int iNum = 0;
7173 
7174  tripoint_abs_ms player_absolute_pos = u.get_location();
7175 
7176  //Display saved zones
7177  for( auto &i : zones ) {
7178  if( iNum >= start_index &&
7179  iNum < start_index + ( ( max_rows > zone_cnt ) ? zone_cnt : max_rows ) ) {
7180  const zone_data &zone = i.get();
7181 
7182  nc_color colorLine = zone.get_enabled() ? c_white : c_light_gray;
7183 
7184  if( iNum == active_index ) {
7185  mvwprintz( w_zones, point( 0, iNum - start_index ), c_yellow, "%s", ">>" );
7186  colorLine = zone.get_enabled() ? c_light_green : c_green;
7187  }
7188 
7189  //Draw Zone name
7190  mvwprintz( w_zones, point( 3, iNum - start_index ), colorLine,
7191  //~ "P: <Zone Name>" represents a personal zone
7192  trim_by_length( ( zone.get_is_personal() ? _( "P: " ) : "" ) + zone.get_name(), 28 ) );
7193 
7195 
7196  //Draw direction + distance
7197  mvwprintz( w_zones, point( 32, iNum - start_index ), colorLine, "%*d %s",
7198  5, static_cast<int>( trig_dist( player_absolute_pos, center ) ),
7199  direction_name_short( direction_from( player_absolute_pos,
7200  center ) ) );
7201 
7202  //Draw Vehicle Indicator
7203  mvwprintz( w_zones, point( 41, iNum - start_index ), colorLine,
7204  zone.get_is_vehicle() ? "*" : "" );
7205  }
7206  iNum++;
7207  }
7208 
7209  // Display zone options
7210  zones_manager_options();
7211  }
7212 
7213  wnoutrefresh( w_zones );
7214  } );
7215 
7216  const int scroll_rate = zone_cnt > 20 ? 10 : 3;
7217  bool quit = false;
7218  bool save = false;
7219  zones_manager_open = true;
7220  zone_manager::get_manager().save_zones( "zmgr-temp" );
7221  while( !quit ) {
7222  if( zone_cnt > 0 ) {
7223  blink = !blink;
7224  const zone_data &zone = zones[active_index].get();
7225  zone_start = m.getlocal( zone.get_start_point() );
7226  zone_end = m.getlocal( zone.get_end_point() );
7227  ctxt.set_timeout( get_option<int>( "BLINK_SPEED" ) );
7228  } else {
7229  blink = false;
7230  zone_start = zone_end = std::nullopt;
7231  ctxt.reset_timeout();
7232  }
7233 
7234  // Actually accessed from the terrain overlay callback `zone_cb` in the
7235  // call to `ui_manager::redraw`.
7236  //NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
7237  zone_blink = blink;
7239 
7241 
7242  //Wait for input
7243  const std::string action = ctxt.handle_input();
7244 
7245  if( action == "ADD_ZONE" ) {
7246  do { // not a loop, just for quick bailing out if canceled
7247  const auto maybe_id = mgr.query_type();
7248  if( !maybe_id.has_value() ) {
7249  break;
7250  }
7251 
7252  const zone_type_id &id = maybe_id.value();
7253  auto options = zone_options::create( id );
7254 
7255  if( !options->query_at_creation() ) {
7256  break;
7257  }
7258 
7259  std::string default_name = options->get_zone_name_suggestion();
7260  if( default_name.empty() ) {
7261  default_name = mgr.get_name_from_type( id );
7262  }
7263  const auto maybe_name = mgr.query_name( default_name );
7264  if( !maybe_name.has_value() ) {
7265  break;
7266  }
7267  const std::string &name = maybe_name.value();
7268 
7269  const auto position = query_position();
7270  if( !position ) {
7271  break;
7272  }
7273 
7274  int vehicle_zones_pre = 0;
7275  for( zone_manager::ref_zone_data zone : get_zones() ) {
7276  if( zone.get().get_is_vehicle() ) {
7277  vehicle_zones_pre++;
7278  }
7279  }
7280 
7281  // TODO: fix point types
7282  mgr.add( name, id, get_player_character().get_faction()->id, false, true,
7283  position->first, position->second, options, false );
7284 
7285  zones = get_zones();
7286  active_index = zone_cnt - 1;
7287 
7288  int vehicle_zones_post = 0;
7289  for( zone_manager::ref_zone_data zone : zones ) {
7290  if( zone.get().get_is_vehicle() ) {
7291  vehicle_zones_post++;
7292  }
7293  }
7294 
7295  if( vehicle_zones_post == vehicle_zones_pre ) {
7296  active_index -= vehicle_zones_post;
7297  }
7298 
7299  stuff_changed = true;
7300  } while( false );
7301 
7302  blink = false;
7303  } else if( action == "ADD_PERSONAL_ZONE" ) {
7304  do { // not a loop, just for quick bailing out if canceled
7305  const auto maybe_id = mgr.query_type( true );
7306  if( !maybe_id.has_value() ) {
7307  break;
7308  }
7309 
7310  const zone_type_id &id = maybe_id.value();
7311  auto options = zone_options::create( id );
7312 
7313  if( !options->query_at_creation() ) {
7314  break;
7315  }
7316 
7317  std::string default_name = options->get_zone_name_suggestion();
7318  if( default_name.empty() ) {
7319  default_name = mgr.get_name_from_type( id );
7320  }
7321  const auto maybe_name = mgr.query_name( default_name );
7322  if( !maybe_name.has_value() ) {
7323  break;
7324  }
7325  const std::string &name = maybe_name.value();
7326 
7327  const auto position = query_position( true );
7328  if( !position ) {
7329  break;
7330  }
7331 
7332  //add a zone that is relative to the avatar position
7333  // TODO: fix point types
7334  mgr.add( name, id, get_player_character().get_faction()->id, false, true,
7335  position->first, position->second, options, true );
7336  zones = get_zones();
7337  active_index = zone_cnt - 1;
7338 
7339  int vehicle_zones = 0;
7340  for( zone_manager::ref_zone_data zone : zones ) {
7341  if( zone.get().get_is_vehicle() ) {
7342  vehicle_zones++;
7343  }
7344  }
7345 
7346  active_index -= vehicle_zones;
7347 
7348  stuff_changed = true;
7349  } while( false );
7350 
7351  blink = false;
7352  } else if( action == "SHOW_ALL_ZONES" ) {
7353  show_all_zones = !show_all_zones;
7354  zones = get_zones();
7355  active_index = 0;
7356  } else if( action == "CHANGE_FACTION" ) {
7357  ui.invalidate_ui();
7358  std::string facname = zones_faction.str();
7360  .description( _( "Show zones for faction:" ) )
7361  .width( 55 )
7362  .max_length( 256 )
7363  .edit( facname );
7364  zones_faction = faction_id( facname );
7365  zones = get_zones();
7366  } else if( action == "QUIT" ) {
7367  if( stuff_changed ) {
7368  const query_ynq_result res = query_ynq( _( "Save changes?" ) );
7369  switch( res ) {
7371  break;
7372  case query_ynq_result::no:
7373  save = false;
7374  quit = true;
7375  break;
7376  case query_ynq_result::yes:
7377  save = true;
7378  quit = true;
7379  break;
7380  }
7381  } else {
7382  save = false;
7383  quit = true;
7384  }
7385  } else if( zone_cnt > 0 ) {
7386  if( navigate_ui_list( action, active_index, scroll_rate, zone_cnt, true ) ) {
7387  blink = false;
7388  } else if( action == "REMOVE_ZONE" ) {
7389  if( active_index < zone_cnt ) {
7390  mgr.remove( zones[active_index] );
7391  zones = get_zones();
7392  active_index--;
7393 
7394  if( active_index < 0 ) {
7395  active_index = 0;
7396  }
7397  }
7398  blink = false;
7399  stuff_changed = true;
7400 
7401  } else if( action == "CONFIRM" ) {
7402  zone_data &zone = zones[active_index].get();
7403 
7404  uilist as_m;
7405  as_m.text = _( "What do you want to change:" );
7406  as_m.entries.emplace_back( 1, true, '1', _( "Edit name" ) );
7407  as_m.entries.emplace_back( 2, true, '2', _( "Edit type" ) );
7408  as_m.entries.emplace_back( 3, zone.get_options().has_options(), '3',
7409  zone.get_type() == zone_type_LOOT_CUSTOM ? _( "Edit filter" ) : _( "Edit options" ) );
7410  as_m.entries.emplace_back( 4, !zone.get_is_vehicle(), '4', _( "Edit position" ) );
7411  as_m.entries.emplace_back( 5, !zone.get_is_vehicle(), '5', _( "Move position" ) );
7412  as_m.query();
7413 
7414  switch( as_m.ret ) {
7415  case 1:
7416  if( zone.set_name() ) {
7417  stuff_changed = true;
7418  }
7419  break;
7420  case 2:
7421  if( zone.set_type() ) {
7422  stuff_changed = true;
7423  }
7424  break;
7425  case 3:
7426  if( zone.get_options().query() ) {
7427  stuff_changed = true;
7428  }
7429  break;
7430  case 4: {
7431  const auto pos = query_position( zone.get_is_personal() );
7432  // FIXME: this comparison is nonsensival in the
7433  // personal zone case because it's between different
7434  // coordinate systems.
7435  if( pos && ( pos->first != zone.get_start_point().raw() ||
7436  pos->second != zone.get_end_point().raw() ) ) {
7437  zone.set_position( *pos );
7438  stuff_changed = true;
7439  }
7440  break;
7441  }
7442  case 5: {
7443  on_out_of_scope invalidate_current_ui( [&]() {
7444  ui.mark_resize();
7445  } );
7446  restore_on_out_of_scope<bool> show_prev( show );
7447  restore_on_out_of_scope<std::optional<tripoint>> zone_start_prev( zone_start );
7448  restore_on_out_of_scope<std::optional<tripoint>> zone_end_prev( zone_end );
7449  show = false;
7450  zone_start = std::nullopt;
7451  zone_end = std::nullopt;
7452  ui.mark_resize();
7453  static_popup message_pop;
7454  message_pop.on_top( true );
7455  message_pop.message( "%s", _( "Moving zone." ) );
7456  const tripoint zone_local_start_point = m.getlocal( zone.get_start_point() );
7457  const tripoint zone_local_end_point = m.getlocal( zone.get_end_point() );
7458  // local position of the zone center, used to calculate the u.view_offset,
7459  // could center the screen to the position it represents
7460  tripoint view_center = m.getlocal( zone.get_center_point() );
7461  const look_around_result result_local = look_around( false, view_center,
7462  zone_local_start_point, false, false,
7463  false, true, zone_local_end_point );
7464  if( result_local.position ) {
7465  const tripoint_abs_ms new_start_point = m.getglobal( *result_local.position );
7466  const tripoint_abs_ms new_end_point = zone.get_end_point() - zone.get_start_point() +
7467  new_start_point;
7468  if( new_start_point == zone.get_start_point() ) {
7469  break; // Nothing changed, don't save
7470  }
7471  if( zone.get_is_personal() ) {
7472  const tripoint_rel_ms new_start_point_rl = new_start_point - u.get_location();
7473  const tripoint_rel_ms new_end_point_rl = new_end_point - u.get_location();
7474  zone.set_position( std::make_pair( new_start_point_rl.raw(), new_end_point_rl.raw() ) );
7475  } else {
7476  zone.set_position( std::make_pair( new_start_point.raw(), new_end_point.raw() ) );
7477  }
7478  stuff_changed = true;
7479  }
7480  }
7481  break;
7482  default:
7483  break;
7484  }
7485 
7486  blink = false;
7487  } else if( action == "MOVE_ZONE_UP" && zone_cnt > 1 ) {
7488  if( active_index < zone_cnt - 1 ) {
7489  mgr.swap( zones[active_index], zones[active_index + 1] );
7490  zones = get_zones();
7491  active_index++;
7492  }
7493  blink = false;
7494  stuff_changed = true;
7495 
7496  } else if( action == "MOVE_ZONE_DOWN" && zone_cnt > 1 ) {
7497  if( active_index > 0 ) {
7498  mgr.swap( zones[active_index], zones[active_index - 1] );
7499  zones = get_zones();
7500  active_index--;
7501  }
7502  blink = false;
7503  stuff_changed = true;
7504 
7505  } else if( action == "SHOW_ZONE_ON_MAP" ) {
7506  //show zone position on overmap;
7507  tripoint_abs_omt player_overmap_position = u.global_omt_location();
7508  tripoint_abs_omt zone_overmap =
7509  project_to<coords::omt>( zones[active_index].get().get_center_point() );
7510 
7511  ui::omap::display_zones( player_overmap_position, zone_overmap, active_index );
7512  } else if( action == "ENABLE_ZONE" ) {
7513  zones[active_index].get().set_enabled( true );
7514 
7515  stuff_changed = true;
7516 
7517  } else if( action == "DISABLE_ZONE" ) {
7518  zones[active_index].get().set_enabled( false );
7519 
7520  stuff_changed = true;
7521 
7522  } else if( action == "TOGGLE_ZONE_DISPLAY" ) {
7523  zones[active_index].get().toggle_display();
7524  stuff_changed = true;
7525 
7526  } else if( action == "ENABLE_PERSONAL_ZONES" ) {
7527  bool zones_changed = false;
7528 
7529  for( const auto &i : zones ) {
7530  zone_data &zone = i.get();
7531  if( zone.get_enabled() ) {
7532  continue;
7533  }
7534  if( zone.get_is_personal() ) {
7535  zone.set_enabled( true );
7536  zones_changed = true;
7537  }
7538  }
7539 
7540  stuff_changed = zones_changed;
7541  } else if( action == "DISABLE_PERSONAL_ZONES" ) {
7542  bool zones_changed = false;
7543 
7544  for( const auto &i : zones ) {
7545  zone_data &zone = i.get();
7546  if( !zone.get_enabled() ) {
7547  continue;
7548  }
7549  if( zone.get_is_personal() ) {
7550  zone.set_enabled( false );
7551  zones_changed = true;
7552  }
7553  }
7554 
7555  stuff_changed = zones_changed;
7556  }
7557  }
7558  }
7559  zones_manager_open = false;
7560  ctxt.reset_timeout();
7561  zone_cb = nullptr;
7562 
7563  if( stuff_changed ) {
7565  if( !save ) {
7566  zones.load_zones( "zmgr-temp" );
7567  }
7568 
7569  zones.cache_data();
7570  }
7571 
7572  u.view_offset = stored_view_offset;
7573 }
These are zones the player can designate.
Definition: clzones.h:349
bool set_type()
Definition: clzones.cpp:650
const zone_options & get_options() const
Definition: clzones.h:490
bool set_name()
Definition: clzones.cpp:633
tripoint_abs_ms get_center_point() const
Definition: clzones.cpp:828
const zone_type_id & get_type() const
Definition: clzones.h:448
std::string get_name() const
Definition: clzones.h:439
tripoint_abs_ms get_end_point() const
Definition: clzones.h:477
bool get_enabled() const
Definition: clzones.h:454
void set_position(const std::pair< tripoint, tripoint > &position, bool manual=true, bool update_avatar=true, bool skip_cache_update=false)
Definition: clzones.cpp:668
bool has_options() const
Definition: clzones.h:487
bool get_is_vehicle() const
Definition: clzones.h:465
bool get_is_personal() const
Definition: clzones.h:468
tripoint_abs_ms get_start_point() const
Definition: clzones.h:471
void set_enabled(bool enabled_arg)
Definition: clzones.cpp:693
std::string get_name_from_type(const zone_type_id &type) const
Definition: clzones.cpp:833
bool remove(zone_data &zone)
Definition: clzones.cpp:1421
std::optional< std::string > query_name(const std::string &default_name="") const
Definition: clzones.cpp:571
std::vector< zone_data > get_zones(const zone_type_id &type, const tripoint_abs_ms &where, const faction_id &fac=your_fac) const
Definition: clzones.cpp:1302
bool has_personal_zones() const
Definition: clzones.cpp:1577
void add(const std::string &name, const zone_type_id &type, const faction_id &faction, bool invert, bool enabled, const tripoint &start, const tripoint &end, const shared_ptr_fast< zone_options > &options=nullptr, bool personal=false, bool silent=false, map *pmap=nullptr)
Definition: clzones.cpp:1385
void cache_avatar_location()
Definition: clzones.cpp:897
void reset_disabled()
Definition: clzones.cpp:881
std::reference_wrapper< zone_data > ref_zone_data
Definition: clzones.h:515
std::optional< zone_type_id > query_type(bool personal=false) const
Definition: clzones.cpp:586
void swap(zone_data &a, zone_data &b)
Definition: clzones.cpp:1468
virtual bool query()
Definition: clzones.h:99
virtual std::vector< std::pair< std::string, std::string > > get_descriptions() const
Definition: clzones.h:109
static shared_ptr_fast< zone_options > create(const zone_type_id &type)
Definition: clzones.cpp:171
virtual bool has_options() const
Definition: clzones.h:87
constexpr int ACTIVITY_SEARCH_DISTANCE
Definition: clzones.h:37
const faction_id your_fac("your_followers")
int trig_dist(const coords::coord_point< Point, Origin, Scale, LhsInBounds > &loc1, const coords::coord_point< Point, Origin, Scale, RhsInBounds > &loc2)
Definition: coordinates.h:762
static void zones_manager_shortcuts(const catacurses::window &w_info, faction_id const &faction)
Definition: game.cpp:6862
static const zone_type_id zone_type_LOOT_CUSTOM("LOOT_CUSTOM")
static void zones_manager_draw_borders(const catacurses::window &w_border, const catacurses::window &w_info_border, const int iInfoHeight, const int width)
Definition: game.cpp:6900
void optional(const JsonObject &jo, const bool was_loaded, const std::string_view name, MemberType &member)
cata_path options()
Definition: path_info.cpp:354
void display_zones(const tripoint_abs_omt &center, const tripoint_abs_omt &select, int iZoneIndex)
Display overmap like with display() and display the given zone.
query_ynq_result query_ynq(const std::string &text)
Definition: output.cpp:851
std::string trim_by_length(const std::string &text, int width)
Definition: output.cpp:278
query_ynq_result
Definition: output.h:431

References _, action, ACTIVITY_SEARCH_DISTANCE, zone_manager::add(), add_draw_callback(), c_green, c_light_gray, c_light_green, c_white, c_yellow, zone_manager::cache_avatar_location(), calcStartPos(), center, zone_options::create(), create_zone_callback(), debug_mode, string_input_popup::description(), direction_from(), direction_name_short(), ui::omap::display_zones(), draw_scrollbar(), string_input_popup::edit(), uilist::entries, faction_id, rotatable_symbols::get(), zone_data::get_center_point(), zone_options::get_descriptions(), zone_data::get_enabled(), zone_data::get_end_point(), zone_data::get_is_personal(), zone_data::get_is_vehicle(), Creature::get_location(), zone_manager::get_manager(), zone_data::get_name(), zone_manager::get_name_from_type(), zone_data::get_options(), get_player_character, zone_data::get_start_point(), zone_data::get_type(), zone_manager::get_zones(), map::getglobal(), map::getlocal(), Creature::global_omt_location(), input_context::handle_input(), zone_options::has_options(), zone_data::has_options(), zone_manager::has_personal_zones(), invalidate_main_ui_adaptor(), look_around(), m, max(), string_input_popup::max_length(), query_popup::message(), min(), mvwprintz(), om_direction::name(), navigate_ui_list(), catacurses::newwin(), no, query_popup::on_top(), optional(), PATH_INFO::options(), point, point_south, point_zero, popup(), Creature::pos(), math_opers::pos(), look_around_result::position, Creature::posx(), Creature::posy(), Creature::posz(), zone_options::query(), uilist::query(), zone_manager::query_name(), zone_manager::query_type(), query_ynq(), quit, coords::coord_point_mut< Point, Subpoint, InBounds >::raw(), ui_manager::redraw(), input_context::register_action(), input_context::register_navigate_ui_list(), zone_manager::remove(), zone_manager::reset_disabled(), input_context::reset_timeout(), uilist::ret, rl_dist(), save(), zone_manager::save_zones(), second, zone_data::set_enabled(), zone_data::set_name(), zone_data::set_position(), input_context::set_timeout(), zone_data::set_type(), show, string_id< T >::str(), zone_manager::swap(), TERMX, TERMY, uilist::text, trig_dist(), trim_by_length(), tripoint, tripoint_zero, u, Character::view_offset, catacurses::werase(), string_input_popup::width(), catacurses::wnoutrefresh(), yes, your_fac(), zone_type_LOOT_CUSTOM, zones, zones_manager_draw_borders(), zones_manager_open, and zones_manager_shortcuts().

Referenced by do_regular_action().

◆ zoom_in()

void game::zoom_in ( )

Definition at line 8171 of file game.cpp.

8172 {
8173 #if defined(TILES)
8174  if( tileset_zoom == 64 ) {
8175  tileset_zoom = MAXIMUM_ZOOM_LEVEL;
8176  } else {
8177  tileset_zoom = tileset_zoom * 2;
8178  }
8179  rescale_tileset( tileset_zoom );
8180 #endif
8181 }

References tileset_zoom.

Referenced by do_regular_action(), list_items(), list_monsters(), and look_around().

◆ zoom_in_overmap()

void game::zoom_in_overmap ( )

Definition at line 8183 of file game.cpp.

8184 {
8185 #if defined(TILES)
8186  if( overmap_tileset_zoom == 64 ) {
8187  overmap_tileset_zoom = MAXIMUM_ZOOM_LEVEL;
8188  } else {
8189  overmap_tileset_zoom *= 2;
8190  }
8191  overmap_tilecontext->set_draw_scale( overmap_tileset_zoom );
8192 #endif
8193 }
int overmap_tileset_zoom
Definition: game.h:1197

References overmap_tileset_zoom.

◆ zoom_out()

void game::zoom_out ( )

Definition at line 8147 of file game.cpp.

8148 {
8149 #if defined(TILES)
8150  if( tileset_zoom > MAXIMUM_ZOOM_LEVEL ) {
8151  tileset_zoom = tileset_zoom / 2;
8152  } else {
8153  tileset_zoom = 64;
8154  }
8155  rescale_tileset( tileset_zoom );
8156 #endif
8157 }

References tileset_zoom.

Referenced by do_regular_action(), list_items(), list_monsters(), and look_around().

◆ zoom_out_overmap()

void game::zoom_out_overmap ( )

Definition at line 8159 of file game.cpp.

8160 {
8161 #if defined(TILES)
8162  if( overmap_tileset_zoom > MAXIMUM_ZOOM_LEVEL ) {
8163  overmap_tileset_zoom /= 2;
8164  } else {
8165  overmap_tileset_zoom = 64;
8166  }
8167  overmap_tilecontext->set_draw_scale( overmap_tileset_zoom );
8168 #endif
8169 }

References overmap_tileset_zoom.

Friends And Related Function Documentation

◆ advanced_inventory

friend class advanced_inventory
friend

Definition at line 145 of file game.h.

◆ Creature_range

friend class Creature_range
friend

Definition at line 389 of file game.h.

Referenced by all_creatures().

◆ do_turn

bool do_turn ( )
friend

MAIN GAME LOOP.

Returns true if game is over (death, saved, quit, etc.).

Definition at line 440 of file do_turn.cpp.

441 {
442  if( g->is_game_over() ) {
444  }
445 
447  // Actual stuff
448  if( g->new_game ) {
449  g->new_game = false;
450  if( get_option<std::string>( "ETERNAL_WEATHER" ) != "normal" ) {
452  ( get_option<std::string>( "ETERNAL_WEATHER" ) );
454  } else {
457  }
458  } else {
459  g->gamemode->per_turn();
460  calendar::turn += 1_turns;
461  }
462 
464 
465  // starting a new turn, clear out temperature cache
466  weather.temperature_cache.clear();
467 
468  if( g->npcs_dirty ) {
469  g->load_npcs();
470  }
471 
475  avatar &u = get_avatar();
476  map &m = get_map();
477  // If controlling a vehicle that is owned by someone else
478  if( u.in_vehicle && u.controlling_vehicle ) {
479  vehicle *veh = veh_pointer_or_null( m.veh_at( u.pos() ) );
480  if( veh && !veh->handle_potential_theft( u, true ) ) {
481  veh->handle_potential_theft( u, false, false );
482  }
483  }
484 
485  // Make sure players cant defy gravity by standing still, Looney tunes style.
486  u.gravity_check();
487 
488  // If you're inside a wall or something and haven't been telefragged, let's get you out.
490  u.stagger();
491  }
492 
493  // If riding a horse - chance to spook
494  if( u.is_mounted() ) {
496  }
497  if( calendar::once_every( 1_days ) ) {
499  }
500 
501  // Move hordes every 2.5 min
503 
504  if( get_option<bool>( "WANDER_SPAWNS" ) ) {
506  }
507  if( u.has_trait( trait_HAS_NEMESIS ) ) {
509  }
510  // Hordes that reached the reality bubble need to spawn,
511  // make them spawn in invisible areas only.
512  m.spawn_monsters( false );
513  }
514 
515  g->debug_hour_timer.print_time();
516 
517  u.update_body();
518 
519  // Auto-save if autosave is enabled
520  if( get_option<bool>( "AUTOSAVE" ) &&
521  calendar::once_every( 1_turns * get_option<int>( "AUTOSAVE_TURNS" ) ) &&
522  !u.is_dead_state() ) {
523  g->autosave();
524  }
525 
527  g->reset_light_level();
528 
529  g->perhaps_add_random_npc( /* ignore_spawn_timers_and_rates = */ false );
530  while( u.get_moves() > 0 && u.activity ) {
531  u.activity.do_turn( u );
532  }
533  // FIXME: hack needed due to the legacy code in advanced_inventory::move_all_items()
534  if( !u.activity ) {
536  }
537 
538  // Process NPC sound events before they move or they hear themselves talking
539  for( npc &guy : g->all_npcs() ) {
540  if( rl_dist( guy.pos(), u.pos() ) < MAX_VIEW_DISTANCE ) {
542  }
543  }
544 
545  music::deactivate_music_id( music::music_id::sound );
546 
547  // Process sound events into sound markers for display to the player.
549 
550  if( u.is_deaf() ) {
552  }
553 
554  if( !u.has_effect( effect_sleep ) || g->uquit == QUIT_WATCH ) {
555  if( u.get_moves() > 0 || g->uquit == QUIT_WATCH ) {
556  while( u.get_moves() > 0 || g->uquit == QUIT_WATCH ) {
557  g->cleanup_dead();
558  g->mon_info_update();
559  // Process any new sounds the player caused during their turn.
560  for( npc &guy : g->all_npcs() ) {
561  if( rl_dist( guy.pos(), u.pos() ) < MAX_VIEW_DISTANCE ) {
563  }
564  }
567  if( !u.activity && g->uquit != QUIT_WATCH
568  && ( !u.has_distant_destination() || calendar::once_every( 10_seconds ) ) ) {
569  g->wait_popup.reset();
571  }
572 
573  if( g->queue_screenshot ) {
574  g->take_screenshot();
575  g->queue_screenshot = false;
576  }
577 
578  if( g->handle_action() ) {
579  ++g->moves_since_last_save;
580  u.action_taken();
581  }
582 
583  if( g->is_game_over() ) {
585  }
586 
587  if( g->uquit == QUIT_WATCH ) {
588  break;
589  }
590  while( u.get_moves() > 0 && u.activity ) {
591  u.activity.do_turn( u );
592  }
593  }
594  // Reset displayed sound markers now that the turn is over.
595  // We only want this to happen if the player had a chance to examine the sounds.
597  } else {
598  // Rate limit key polling to 10 times a second.
599  static auto start = std::chrono::time_point_cast<std::chrono::milliseconds>(
600  std::chrono::steady_clock::now() );
601  const auto now = std::chrono::time_point_cast<std::chrono::milliseconds>(
602  std::chrono::steady_clock::now() );
603  if( ( now - start ).count() > 100 ) {
605  start = now;
606  }
607 
608  g->mon_info_update();
609 
610  // If player is performing a task, a monster is dangerously close,
611  // and monster can reach to the player or it has some sort of a ranged attack,
612  // warn them regardless of previous safemode warnings
613  if( u.activity ) {
614  for( std::pair<const distraction_type, std::string> &dist : u.activity.get_distractions() ) {
615  if( g->cancel_activity_or_ignore_query( dist.first, dist.second ) ) {
616  break;
617  }
618  }
619  }
620  }
621  }
622 
623  if( g->driving_view_offset.x != 0 || g->driving_view_offset.y != 0 ) {
624  // Still have a view offset, but might not be driving anymore,
625  // or the option has been deactivated,
626  // might also happen when someone dives from a moving car.
627  // or when using the handbrake.
628  vehicle *veh = veh_pointer_or_null( m.veh_at( u.pos() ) );
629  g->calc_driving_offset( veh );
630  }
631 
633  // No-scent debug mutation has to be processed here or else it takes time to start working
634  if( !u.has_flag( STATIC( json_character_flag( "NO_SCENT" ) ) ) ) {
635  scent.set( u.pos(), u.scent, u.get_type_of_scent() );
637  }
638  scent.update( u.pos(), m );
639 
640  // We need floor cache before checking falling 'n stuff
642 
643  m.process_falling();
644  m.vehmove();
645  m.process_fields();
646  m.process_items();
648  m.creature_in_field( u );
649 
650  // Apply sounds from previous turn to monster and NPC AI.
652  const int levz = m.get_abs_sub().z();
653  // Update vision caches for monsters. If this turns out to be expensive,
654  // consider a stripped down cache just for monsters.
655  m.build_map_cache( levz, true );
656  monmove();
657  if( calendar::once_every( 5_minutes ) ) {
659  }
660  if( calendar::once_every( 10_seconds ) ) {
661  for( const tripoint &elem : m.get_furn_field_locations() ) {
662  const furn_t &furn = *m.furn( elem );
663  for( const emit_id &e : furn.emissions ) {
664  m.emit_field( elem, e );
665  }
666  }
667  for( const tripoint &elem : m.get_ter_field_locations() ) {
668  const ter_t &ter = *m.ter( elem );
669  for( const emit_id &e : ter.emissions ) {
670  m.emit_field( elem, e );
671  }
672  }
673  }
674  g->mon_info_update();
675  u.process_turn();
676  if( u.get_moves() < 0 && get_option<bool>( "FORCE_REDRAW" ) ) {
678  refresh_display();
679  }
680 
681  if( levz >= 0 && !u.is_underwater() ) {
683  }
684 
685  const bool player_is_sleeping = u.has_effect( effect_sleep );
686  bool wait_redraw = false;
687  std::string wait_message;
688  time_duration wait_refresh_rate;
689  if( player_is_sleeping ) {
690  wait_redraw = true;
691  wait_message = _( "Wait till you wake up…" );
692  wait_refresh_rate = 30_minutes;
693  } else if( const std::optional<std::string> progress = u.activity.get_progress_message( u ) ) {
694  wait_redraw = true;
695  wait_message = *progress;
697  wait_message += string_format( _( "\n%s to interrupt" ), press_x( ACTION_PAUSE ) );
698  }
699  if( u.activity.id() == ACT_AUTODRIVE ) {
700  wait_refresh_rate = 1_turns;
701  } else if( u.activity.id() == ACT_FIRSTAID ) {
702  wait_refresh_rate = 5_turns;
703  } else {
704  wait_refresh_rate = 5_minutes;
705  }
706  }
707  if( wait_redraw ) {
708  if( g->first_redraw_since_waiting_started ||
709  calendar::once_every( std::min( 1_minutes, wait_refresh_rate ) ) ) {
710  if( g->first_redraw_since_waiting_started || calendar::once_every( wait_refresh_rate ) ) {
712  }
713 
714  // Avoid redrawing the main UI every time due to invalidation
716  g->wait_popup = std::make_unique<static_popup>();
717  g->wait_popup->on_top( true ).wait_message( "%s", wait_message );
719  refresh_display();
720  g->first_redraw_since_waiting_started = false;
721  }
722  } else {
723  // Nothing to wait for now
724  g->wait_popup.reset();
725  g->first_redraw_since_waiting_started = true;
726  }
727 
729 
730  u.update_bodytemp();
733 
734  if( calendar::once_every( 1_minutes ) ) {
735  u.update_morale();
736  for( npc &guy : g->all_npcs() ) {
737  guy.update_morale();
738  guy.check_and_recover_morale();
739  }
740  }
741 
742  if( calendar::once_every( 9_turns ) ) {
744  }
745 
746  if( !u.is_deaf() ) {
748  }
753 
754  // reset player noise
755  u.volume = 0;
756 
757  // Calculate bionic power balance
760 
761 #if defined(EMSCRIPTEN)
762  // This will cause a prompt to be shown if the window is closed, until the
763  // game is saved.
764  EM_ASM( window.game_unsaved = true; );
765 #endif
766 
767  return false;
768 }
void kill_advanced_inv()
void update_morale()
Ticks down morale counters and removes them.
void action_taken()
Called after every action, invalidates player caches.
Definition: character.cpp:1411
bool check_mount_is_spooked()
Definition: character.cpp:1670
void apply_wetness_morale(units::temperature temperature)
Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature.
Definition: suffer.cpp:1936
int volume
Definition: character.h:600
void gravity_check()
void check_and_recover_morale()
Checks permanent morale for consistency and recovers it when an inconsistency is found.
scenttype_id get_type_of_scent() const
Definition: character.cpp:8551
void update_body_wetness(const w_point &weather)
Maintains body wetness and handles the rate at which the player dries.
void stagger()
bool is_deaf() const
Definition: character.cpp:4614
void update_bodytemp()
Maintains body temperature.
void update_body()
Updates all "biology" by one turn.
units::energy power_prev_turn
Definition: avatar.h:370
units::energy power_balance
Definition: avatar.h:372
friend scent_map & get_scent()
Definition: game.cpp:13851
void build_floor_caches()
Definition: map.cpp:9475
void process_falling()
Invoked drop_everything on cached dirty tiles.
Definition: map.cpp:3058
void emit_field(const tripoint &pos, const emit_id &src, float mul=1.0f)
Runs one cycle of emission src which may result in propagation of fields.
Definition: map_field.cpp:2102
const std::vector< tripoint > & get_furn_field_locations() const
Definition: map.cpp:9042
void vehmove()
Definition: map.cpp:640
const std::vector< tripoint > & get_ter_field_locations() const
Definition: map.cpp:9047
void process_fields()
Definition: map_field.cpp:162
void process_items()
Definition: map.cpp:5663
static void process_all()
Handles mission deadline processing.
Definition: mission.cpp:126
void move_nemesis()
moves 'nemesis' horde spawned by the "hunted" trait across every overmap regardless of distance from ...
void set_scent(const tripoint_abs_omt &loc, int strength)
Method to set a scent trace.
void process_mongroups()
Process nearby monstergroups (dying mostly).
void move_hordes()
Let hordes move a step.
std::map< distraction_type, std::string > get_distractions() const
void do_turn(Character &you)
Performs the activity for a single turn.
bool is_interruptible() const
std::optional< std::string > get_progress_message(const avatar &u) const
Helper that returns an activity specific progress message.
bool interruptable_with_kb
Controls whether this activity can be cancelled with 'pause' action.
void set(const tripoint &p, int value, const scenttype_id &type=scenttype_id())
Get the scent value at the given position.
Definition: scent_map.cpp:103
void update(const tripoint &center, map &m)
Definition: scent_map.cpp:162
static constexpr time_duration from_minutes(const T m)
Definition: calendar.h:233
void process()
Process all queued events, potentially altering the game state and modifying the event queue.
pimpl< w_point > weather_precise
Definition: weather.h:216
std::unordered_map< tripoint, units::temperature > temperature_cache
temperature cache, cleared every turn, sparse map of map tripoints to temperatures
Definition: weather.h:225
static const activity_id ACT_AUTODRIVE("ACT_AUTODRIVE")
static const trait_id trait_HAS_NEMESIS("HAS_NEMESIS")
static const efftype_id effect_sleep("sleep")
static const activity_id ACT_FIRSTAID("ACT_FIRSTAID")
void handle_weather_effects(const weather_type_id &w)
Definition: weather.cpp:444
void set_nextweather(time_point t)
Definition: weather.cpp:951
void process_explosions()
Definition: explosion.cpp:907
void deactivate_music_id(music_id data)
Definition: music.cpp:64
std::string get_music_id_string()
Definition: music.cpp:49
void do_vehicle_engine_sfx()
Definition: sounds.cpp:2014
void do_hearing_loss(int turns=-1)
Definition: sounds.cpp:2009
void do_sleepiness()
Definition: sounds.cpp:2034
void do_danger_music()
Definition: sounds.cpp:2013
void do_vehicle_exterior_engine_sfx()
Definition: sounds.cpp:2015
void remove_hearing_loss()
Definition: sounds.cpp:2010
void process_sounds()
Definition: sounds.cpp:472
void reset_markers()
Definition: sounds.cpp:792
bool cleanup_at_end()
Definition: do_turn.cpp:103
void play_music(const std::string &)
Definition: sdlsound.h:25
std::set< emit_id > emissions
Emissions of furniture.
Definition: mapdata.h:653
std::set< emit_id > emissions
Definition: mapdata.h:620

◆ editmap

friend class editmap
friend

Definition at line 144 of file game.h.

◆ exosuit_interact

friend class exosuit_interact
friend

Definition at line 147 of file game.h.

◆ get_achievements

achievements_tracker& get_achievements ( )
friend

Definition at line 13802 of file game.cpp.

13803 {
13804  return g->achievements();
13805 }

Referenced by save_achievements().

◆ get_avatar

avatar& get_avatar ( )
friend

◆ get_creature_tracker

creature_tracker& get_creature_tracker ( )
friend

◆ get_event_bus

event_bus& get_event_bus ( )
friend

Definition at line 13832 of file game.cpp.

13833 {
13834  return g->events();
13835 }

Referenced by cata_event_dispatch::avatar_moves(), bury_screen(), and start_game().

◆ get_globals

global_variables& get_globals ( )
friend

Definition at line 13871 of file game.cpp.

13872 {
13873  return g->global_variables_instance;
13874 }

Referenced by setup().

◆ get_map

map& get_map ( )
friend

◆ get_memorial

memorial_logger& get_memorial ( )
friend

Definition at line 13837 of file game.cpp.

13838 {
13839  return g->memorial();
13840 }

◆ get_player_character

Character& get_player_character ( )
friend

◆ get_player_view

viewer& get_player_view ( )
friend

Definition at line 13812 of file game.cpp.

13813 {
13814  return g->u;
13815 }

◆ get_scenario

const scenario* get_scenario ( )
friend

Definition at line 13842 of file game.cpp.

13843 {
13844  return g->scen;
13845 }

Referenced by start_game().

◆ get_scent

scent_map& get_scent ( )
friend

Definition at line 13851 of file game.cpp.

13852 {
13853  return g->scent;
13854 }

◆ get_stats

stats_tracker& get_stats ( )
friend

Definition at line 13856 of file game.cpp.

13857 {
13858  return g->stats();
13859 }

◆ get_timed_events

timed_event_manager& get_timed_events ( )
friend

Definition at line 13861 of file game.cpp.

13862 {
13863  return g->timed_events;
13864 }

Referenced by do_regular_action(), and print_terrain_info().

◆ get_weather

weather_manager& get_weather ( )
friend

Definition at line 13866 of file game.cpp.

13867 {
13868  return g->weather;
13869 }

Referenced by is_in_sunlight(), natural_light_level(), and setup().

◆ main_menu

friend class main_menu
friend

Definition at line 146 of file game.h.

◆ monster_range

friend class monster_range
friend

Definition at line 388 of file game.h.

Referenced by all_monsters().

◆ set_scenario

void set_scenario ( const scenario new_scenario)
friend

Definition at line 13846 of file game.cpp.

13847 {
13848  g->scen = new_scenario;
13849 }

◆ turn_handler::cleanup_at_end

Member Data Documentation

◆ achievements_tracker_ptr

pimpl<achievements_tracker> game::achievements_tracker_ptr
private

Definition at line 1071 of file game.h.

Referenced by achievements(), death_screen(), game(), serialize(), setup(), and unserialize().

◆ async_anim_layer_curses

std::map<tripoint, std::pair <std::string, nc_color> > game::async_anim_layer_curses
protected

◆ auto_travel_mode

bool game::auto_travel_mode = false

Definition at line 1138 of file game.h.

Referenced by do_regular_action(), serialize(), and unserialize().

◆ blink_active_phase

bool game::blink_active_phase = true

Definition at line 265 of file game.h.

Referenced by draw().

◆ blink_layer_curses

std::map<tripoint, std::pair <std::string, nc_color> > game::blink_layer_curses
protected

◆ bVMonsterLookFire

bool game::bVMonsterLookFire = false
private

Definition at line 1165 of file game.h.

Referenced by list_monsters(), look_around(), serialize(), setup(), and unserialize().

◆ critter_died

bool game::critter_died = false
private

Has anything died in this turn and needs to be cleaned up?

Definition at line 1184 of file game.h.

Referenced by cleanup_dead(), and set_critter_died().

◆ critter_tracker

pimpl<creature_tracker> game::critter_tracker

◆ debug_hour_timer

◆ debug_pathfinding

bool game::debug_pathfinding = false

Definition at line 1121 of file game.h.

◆ destination_preview

std::vector<tripoint_bub_ms> game::destination_preview
private

◆ displaying_lighting_condition

int game::displaying_lighting_condition = 0

Type of lighting condition overlay to display.

Definition at line 1133 of file game.h.

◆ displaying_overlays

std::optional<action_id> game::displaying_overlays
private

Definition at line 1029 of file game.h.

Referenced by display_overlay_state(), and display_toggle_overlay().

◆ displaying_visibility_creature

Creature* game::displaying_visibility_creature

Creature for which to display the visibility map.

Definition at line 1131 of file game.h.

Referenced by display_visibility().

◆ draw_callbacks

std::vector<weak_ptr_fast<draw_callback_t> > game::draw_callbacks
private

Definition at line 247 of file game.h.

Referenced by add_draw_callback(), and draw().

◆ driving_view_offset

point game::driving_view_offset

Definition at line 1118 of file game.h.

Referenced by calc_driving_offset(), serialize(), set_driving_view_offset(), and unserialize().

◆ eoc_events_ptr

pimpl<eoc_events> game::eoc_events_ptr
private

Definition at line 1075 of file game.h.

Referenced by game(), and setup().

◆ event_bus_ptr

pimpl<event_bus> game::event_bus_ptr
private

Definition at line 1069 of file game.h.

Referenced by events().

◆ faction_manager_ptr

pimpl<faction_manager> game::faction_manager_ptr

◆ first_redraw_since_waiting_started

bool game::first_redraw_since_waiting_started = true
private

Is this the first redraw since waiting (sleeping or activity) started.

Definition at line 1186 of file game.h.

Referenced by game().

◆ follower_ids

std::set<character_id> game::follower_ids
private

◆ fullscreen

bool game::fullscreen = false

◆ gamemode

std::unique_ptr<special_game> game::gamemode
private

Definition at line 1190 of file game.h.

Referenced by death_screen(), gametype(), handle_action(), has_gametype(), load(), and start_game().

◆ global_variables_instance

global_variables game::global_variables_instance
private

Definition at line 1087 of file game.h.

Referenced by serialize(), and unserialize().

◆ inactive_global_effect_on_condition_vector

std::vector<effect_on_condition_id> game::inactive_global_effect_on_condition_vector

Definition at line 1094 of file game.h.

Referenced by serialize(), and unserialize().

◆ is_looking

bool game::is_looking = false
private

Definition at line 246 of file game.h.

Referenced by draw_ter(), and look_around().

◆ kill_tracker_ptr

pimpl<kill_tracker> game::kill_tracker_ptr
private

Definition at line 1072 of file game.h.

Referenced by game(), get_kill_tracker(), serialize(), setup(), and unserialize().

◆ last_mouse_edge_scroll

std::chrono::time_point<std::chrono::steady_clock> game::last_mouse_edge_scroll
private

Definition at line 1206 of file game.h.

Referenced by mouse_edge_scrolling().

◆ last_mouse_edge_scroll_vector_overmap

tripoint game::last_mouse_edge_scroll_vector_overmap
private

Definition at line 1208 of file game.h.

Referenced by mouse_edge_scrolling_overmap(), and mouse_edge_scrolling_terrain().

◆ last_mouse_edge_scroll_vector_terrain

tripoint game::last_mouse_edge_scroll_vector_terrain
private

Definition at line 1207 of file game.h.

Referenced by mouse_edge_scrolling_overmap(), and mouse_edge_scrolling_terrain().

◆ last_save_timestamp

std::time_t game::last_save_timestamp = 0
private

Definition at line 1175 of file game.h.

Referenced by autosave(), init_autosave(), quickload(), and quicksave().

◆ latest_lightlevels

std::array<float, OVERMAP_LAYERS> game::latest_lightlevels
mutableprivate

Definition at line 1177 of file game.h.

Referenced by natural_light_level(), and reset_light_level().

◆ list_item_downvote

std::string game::list_item_downvote
private

Definition at line 1162 of file game.h.

Referenced by list_items().

◆ list_item_upvote

std::string game::list_item_upvote
private

Definition at line 1161 of file game.h.

Referenced by list_items().

◆ liveview

live_view& game::liveview
private

Definition at line 1066 of file game.h.

Referenced by draw_look_around_cursor(), and handle_mouseview().

◆ liveview_ptr

pimpl<live_view> game::liveview_ptr
private

Definition at line 1065 of file game.h.

◆ m

map& game::m
private

Definition at line 1077 of file game.h.

Referenced by cata_event_dispatch::avatar_moves(), butcher(), can_move_furniture(), catch_a_monster(), check_near_zone(), check_zone(), climb_down_menu_gen(), climb_down_using(), control_vehicle(), disp_NPCs(), do_regular_action(), draw(), draw_bullet(), draw_critter(), draw_hit_mon(), draw_look_around_cursor(), draw_minimap(), draw_ter(), examine(), extended_description(), find_nearby_items(), fling_creature(), forced_door_closing(), get_cur_om(), get_dangerous_tile(), get_fishable_locations(), get_player_input(), get_veh_dir_indicator_location(), grabbed_furn_move(), grabbed_furn_move_time(), grabbed_veh_move(), is_empty(), is_game_over(), is_sheltered(), knockback(), list_monsters(), load(), load_map(), load_npcs(), look_around(), mon_info_update(), moving_vehicle_dismount(), peek(), phasing_move(), pickup(), place_critter_around(), place_player(), place_player_overmap(), place_vehicle_nearby(), points_in_range(), pre_print_all_tile_info(), print_all_tile_info(), print_fields_info(), print_furniture_info(), print_graffiti_info(), print_items_info(), print_part_con_info(), print_terrain_info(), print_trap_info(), prompt_dangerous_tile(), random_point(), remoteveh(), save_cyborg(), save_maps(), serialize(), setup(), shift_monsters(), slip_down(), start_game(), start_hauling(), swap_critters(), try_get_right_click_action(), update_map(), use_computer(), validate_camps(), validate_linked_vehicles(), validate_mounted_npcs(), vertical_move(), vertical_notes(), vertical_shift(), walk_move(), wield(), and zones_manager().

◆ main_ui_adaptor

weak_ptr_fast<ui_adaptor> game::main_ui_adaptor
private

◆ map_ptr

pimpl<map> game::map_ptr
private

Definition at line 1063 of file game.h.

◆ memorial_logger_ptr

pimpl<memorial_logger> game::memorial_logger_ptr
private

Definition at line 1073 of file game.h.

Referenced by game(), and memorial().

◆ mostseen

int game::mostseen = 0

◆ moves_since_last_save

int game::moves_since_last_save = 0
private

Definition at line 1174 of file game.h.

Referenced by get_moves_since_last_save(), init_autosave(), quickload(), and quicksave().

◆ new_game

bool game::new_game = false

True if the game has just started or loaded, else false.

Definition at line 1105 of file game.h.

Referenced by setup(), and start_game().

◆ next_mission_id

int game::next_mission_id = 0
private

Definition at line 1167 of file game.h.

Referenced by assign_mission_id(), serialize_master(), setup(), and unserialize_master().

◆ next_npc_id

character_id game::next_npc_id
private

Definition at line 1166 of file game.h.

Referenced by assign_npc_id(), serialize_master(), setup(), and unserialize_master().

◆ npcs_dirty

bool game::npcs_dirty = false
private

Has a NPC been spawned since last load?

Definition at line 1182 of file game.h.

Referenced by load_npcs(), and set_npcs_dirty().

◆ overmap_tileset_zoom

int game::overmap_tileset_zoom = DEFAULT_TILESET_ZOOM
private

Definition at line 1197 of file game.h.

Referenced by zoom_in_overmap(), and zoom_out_overmap().

◆ queue_screenshot

bool game::queue_screenshot = false

Definition at line 1139 of file game.h.

◆ queued_global_effect_on_conditions

queued_eocs game::queued_global_effect_on_conditions

Definition at line 1095 of file game.h.

Referenced by serialize(), and unserialize().

◆ remoteveh_cache

vehicle* game::remoteveh_cache
private

Definition at line 1180 of file game.h.

Referenced by remoteveh(), setremoteveh(), and setup().

◆ remoteveh_cache_time

time_point game::remoteveh_cache_time
private

Definition at line 1179 of file game.h.

Referenced by remoteveh(), setremoteveh(), and setup().

◆ safe_mode

safe_mode_type game::safe_mode

◆ safe_mode_warning_logged

bool game::safe_mode_warning_logged = false
private

Definition at line 1164 of file game.h.

Referenced by check_safe_mode_allowed(), do_regular_action(), and set_safe_mode().

◆ scen

const scenario* game::scen = nullptr
private

Definition at line 1081 of file game.h.

Referenced by start_calendar(), and start_game().

◆ scent

scent_map& game::scent
private

Definition at line 1079 of file game.h.

Referenced by display_scent(), serialize(), setup(), unserialize(), update_map(), and vertical_shift().

◆ scent_ptr

pimpl<scent_map> game::scent_ptr
private

Definition at line 1067 of file game.h.

◆ seed

unsigned int game::seed = 0
private

Seed for all the random numbers that should have consistent randomness (weather).

Definition at line 1200 of file game.h.

Referenced by get_seed(), serialize_master(), start_game(), and unserialize_master().

◆ sFilter

std::string game::sFilter
private

Definition at line 1160 of file game.h.

Referenced by list_items(), and reset_item_list_state().

◆ show_panel_adm

bool game::show_panel_adm = false

Definition at line 1135 of file game.h.

Referenced by draw_panels(), and load_static_data().

◆ spell_events_ptr

pimpl<spell_events> game::spell_events_ptr
private

Definition at line 1074 of file game.h.

Referenced by game(), and spell_events_subscriber().

◆ stats_tracker_ptr

pimpl<stats_tracker> game::stats_tracker_ptr
private

Definition at line 1070 of file game.h.

Referenced by game(), serialize(), stats(), and unserialize().

◆ ter_view_p

tripoint game::ter_view_p

Definition at line 1107 of file game.h.

Referenced by draw(), draw_ter(), handle_action(), handle_mouseview(), and look_around().

◆ tileset_zoom

int game::tileset_zoom = 0
private

How far the tileset should be zoomed out, 16 is default.

32 is zoomed in by x2, 8 is zoomed out by x0.5

Definition at line 1196 of file game.h.

Referenced by get_zoom(), look_around(), mouse_edge_scrolling_terrain(), reset_zoom(), set_zoom(), zoom_in(), and zoom_out().

◆ time_of_last_load

std::chrono::time_point<std::chrono::steady_clock> game::time_of_last_load
private

Definition at line 1173 of file game.h.

Referenced by load(), save(), and start_game().

◆ time_played_at_last_load

std::chrono::seconds game::time_played_at_last_load
private

Definition at line 1171 of file game.h.

Referenced by load(), save(), and start_game().

◆ timed_event_manager_ptr

pimpl<timed_event_manager> game::timed_event_manager_ptr
private

Definition at line 1068 of file game.h.

◆ timed_events

timed_event_manager& game::timed_events
private

Definition at line 1084 of file game.h.

Referenced by natural_light_level(), and setup().

◆ turnssincelastmon

time_duration game::turnssincelastmon = 0_turns

Definition at line 1144 of file game.h.

Referenced by do_regular_action(), mon_info_update(), serialize(), setup(), and unserialize().

◆ u

avatar& game::u
private

Definition at line 1078 of file game.h.

Referenced by add_npc_follower(), cata_event_dispatch::avatar_moves(), bury_screen(), butcher(), calc_driving_offset(), can_move_furniture(), cancel_activity_or_ignore_query(), cancel_activity_query(), catch_a_monster(), centerlistview(), chat(), check_safe_mode_allowed(), control_vehicle(), create_starting_npcs(), critter_by_id(), death_screen(), disable_robot(), disp_NPCs(), display_scent(), do_regular_action(), draw(), draw_async_anim_curses(), draw_blink_curses(), draw_critter(), draw_hit_mon(), draw_line(), draw_look_around_cursor(), draw_minimap(), draw_panels(), draw_ter(), draw_trail_to_square(), draw_veh_dir_indicator(), drop_in_direction(), exam_appliance(), exam_vehicle(), examine(), extended_description(), favorite_ammo_or_select(), find_nearby_items(), find_or_make_stairs(), fling_creature(), forced_door_closing(), get_dangerous_tile(), get_player_input(), get_veh_dir_indicator_location(), grabbed_furn_move(), grabbed_furn_move_time(), grabbed_move(), grabbed_veh_move(), insert_item(), inv_map_splice(), inventory_item_menu(), is_game_over(), is_hostile_within(), is_in_dangerous_field(), is_in_viewport(), item_action_menu(), knockback(), list_items(), list_items_monsters(), list_monsters(), load(), look_around(), mon_info_update(), move_save_to_graveyard(), moving_vehicle_dismount(), npc_menu(), on_move_effects(), open_gate(), peek(), perhaps_add_random_npc(), phasing_move(), pickup(), pickup_all(), place_player(), place_player_overmap(), portal_storm_query(), print_all_tile_info(), print_creature_info(), print_items_info(), print_terrain_info(), print_trap_info(), prompt_dangerous_tile(), quickload(), reload(), reload_item(), reload_weapon(), reload_wielded(), remoteveh(), remove_npc_follower(), save(), save_achievements(), save_player_data(), serialize(), set_driving_view_offset(), setremoteveh(), setup(), shared_from(), slip_down(), slip_down_chance(), start_game(), start_hauling(), try_get_left_click_action(), try_get_right_click_action(), unload_container(), unserialize(), update_map(), update_overmap_seen(), use_computer(), validate_camps(), validate_npc_followers(), vertical_move(), vertical_notes(), vertical_shift(), walk_move(), wield(), write_memorial_file(), and zones_manager().

◆ u_ptr

pimpl<avatar> game::u_ptr
private

Definition at line 1064 of file game.h.

◆ u_shared_ptr

shared_ptr_fast<Character> game::u_shared_ptr
private

Definition at line 1154 of file game.h.

Referenced by shared_from().

◆ unique_npcs

std::unordered_map<std::string, point_abs_om> game::unique_npcs
private

◆ uquit

quit_status game::uquit

Used in main.cpp to determine what type of quit is being performed.

Definition at line 1103 of file game.h.

Referenced by bury_screen(), do_regular_action(), get_player_input(), handle_action(), is_game_over(), quickload(), and setup().

◆ user_action_counter

int game::user_action_counter = 0
private

Definition at line 1193 of file game.h.

Referenced by get_user_action_counter(), and handle_action().

◆ w_minimap

catacurses::window game::w_minimap

Definition at line 1111 of file game.h.

Referenced by create_or_get_main_ui_adaptor(), and draw_minimap().

◆ w_minimap_ptr

catacurses::window game::w_minimap_ptr
private

Definition at line 1157 of file game.h.

Referenced by create_or_get_main_ui_adaptor().

◆ w_omlegend

catacurses::window game::w_omlegend

Definition at line 1110 of file game.h.

◆ w_overmap

catacurses::window game::w_overmap

Definition at line 1109 of file game.h.

◆ w_pixel_minimap

catacurses::window game::w_pixel_minimap

◆ w_terrain

catacurses::window game::w_terrain

◆ w_terrain_ptr

catacurses::window game::w_terrain_ptr
private

Definition at line 1156 of file game.h.

Referenced by create_or_get_main_ui_adaptor().

◆ wait_popup

std::unique_ptr<static_popup> game::wait_popup
private

Definition at line 1214 of file game.h.

◆ was_fullscreen

bool game::was_fullscreen = false

Definition at line 1137 of file game.h.

Referenced by load_static_data(), reenter_fullscreen(), and temp_exit_fullscreen().

◆ weather

weather_manager game::weather
private

Definition at line 1146 of file game.h.

Referenced by get_player_input(), place_player_overmap(), setup(), and start_game().

◆ zones_manager_open

bool game::zones_manager_open = false
private

Is Zone manager open or not - changes graphics of some zone tiles.

Definition at line 1188 of file game.h.

Referenced by is_zones_manager_open(), and zones_manager().


The documentation for this class was generated from the following files: